最近看了一些有关数据结构c语言描述下的视频,整理好了自己的思路,按照自己的想法写了一篇数据结构单链表的操作,为自己考研之路留下一些痕迹。
1.首先创建结构体,声明静态的全局变量
typedef int ElemType; typedef struct Node{ ElemType data; //储存数据 struct Node *next; //指向下一个元素 }node,*link; static int num=0; //单链表的长度
2.接下来是单循环链表的创建
void initList(link &T) { link currentNode,temp; //目前位置的节点 和开始节点 int number; //申请链表的长度 int data; //数据 printf("请输入你想要创建链表的长度"); scanf("%d",&number); num=number; //全局变量中单链表的长度 T=(Node*)malloc(sizeof(Node)); if(!T) { printf("空间申请失败 "); } T->next=NULL; temp=T; // 开始节点 //实行尾插法 printf("请依次输入链表储存的数值 "); if(number>0) { while(number--) //temp指向的是链表中最后一个元素 { scanf("%d",&data); currentNode=(Node*)malloc(sizeof(Node)); if(!currentNode) { printf("空间申请失败"); } currentNode->data=data; currentNode->next=NULL; //生成新的结点 temp->next=currentNode; temp=currentNode; //结点向下移一位 } temp->next=T->next; //实现单链循环 } }
3.单循环链表的尾部添加操作
void addList(link T,int *e) { link currentNode=(Node*)malloc(sizeof(Node)); currentNode->data=*e; currentNode->next=NULL; if(!currentNode) { printf("空间申请失败 "); } if(num==0) //如果链表的元素为0 { T->next=currentNode; currentNode->next=currentNode; num++; //链表数量增加 } else //链表不为空时 { link firstNode=T->next; //定义第一个结点 (非头结点) while(firstNode->next!=T->next)//不是尾结点 { firstNode=firstNode->next; //循环到尾结点点 } currentNode->next=T->next; //实现尾结点循环 firstNode->next=currentNode; num++; //链表数量增加 } }
4.单循环链表的插入操作,出现以下3种情况
(1).链表为空时
(2)链表不为空,在链尾插入
(3)链表不为空,在链的中间插入
//插入数据 void insertList(link T,int i, int *e) { link currentNode=(Node*)malloc(sizeof(Node)); currentNode->data=*e; currentNode->next=NULL; //插入数据的临时结点 if(i<0||i>num+1) { printf("插入的数据不合理 "); } else if(num==0)//链表为空 则i必须为1 { T->next=currentNode; currentNode->next=currentNode; num++; //链表数量增加 } else if(i==num+1) //在尾部添加 { link firstNode=T->next; //定义第一个结点 (非头结点) while(firstNode->next!=T->next)//不是尾结点 { firstNode=firstNode->next; //循环到尾结点点 } currentNode->next=T->next; //实现尾结点循环 firstNode->next=currentNode; num++; //链表数量增加 } else //在链表的中间插入 { //先要找到插入元素的前一个位置 for(int j=0;j<i-1;j++) { T=T->next; } currentNode->next=T->next; T->next=currentNode; num++; //链表数量增加 } }
5.单循环链表的删除操作
(1)链表只有一个元素结点时
(2)在链表末尾进行删除
(3)在链表的中间进行删除操作
void deleteList(link T,int i) { if(i<1||i>num||num==0) { printf("无法删除 "); } else if(num==1) //链表只有一个元素 { free(T->next); //避免空间泄露 T->next=NULL; num--; //链表长度减少 } else if(i==num) //删除链表的最后一个元素 { link temp=T; //生成临时结点 for(int j=0;j<i-1;j++) { temp=temp->next; //循环到尾结点的前一个结点 } free(temp->next); //避免空间泄露 temp->next=T->next; //指向头结点 num--; //链表长度减少 } else //删除中间结点 { link temp=T; //生成临时结点 for(int j=0;j<i-1;j++) { temp=temp->next; //循环到尾该点的前一个结点 } link deleteNode=temp->next; //指向要删除的节点 temp->next=temp->next->next; free(deleteNode); //避免空间泄露 num--; //链表长度减少 } }
6.获取元素值得操作
ElemType getElem(link T,int i) { if(i<1||i>num||num==0) { printf("无法获取 "); return -1; } else { for(int j=0;j<i;j++) { T=T->next; //循环到当前结点 } return T->data; } }
7.打印操作
//打印操作 void printf(link T) { for(int j=0;j<num;j++) { T=T->next; printf("%d ",T->data); } printf(" "); }
8.销毁操作
//销毁操作 void clearList(link T) { link currentNode=T->next; //第一个结点 link temp; while(currentNode->next!=T->next) { temp=currentNode->next; free(currentNode); currentNode=temp; } T->next=NULL; num=0; }
所有的代码如下:
#include<stdlib.h> #include<stdio.h> typedef int ElemType; typedef struct Node{ ElemType data; //储存数据 struct Node *next; //指向下一个元素 }node,*link; static int num=0; //单链表的长度 //循环链表的创建 void initList(link &T) { link currentNode,temp; //目前位置的节点 和开始节点 int number; //申请链表的长度 int data; //数据 printf("请输入你想要创建链表的长度"); scanf("%d",&number); num=number; //全局变量中单链表的长度 T=(Node*)malloc(sizeof(Node)); if(!T) { printf("空间申请失败 "); } T->next=NULL; temp=T; // 开始节点 //实行尾插法 printf("请依次输入链表储存的数值 "); if(number>0) { while(number--) //temp指向的是链表中最后一个元素 { scanf("%d",&data); currentNode=(Node*)malloc(sizeof(Node)); if(!currentNode) { printf("空间申请失败"); } currentNode->data=data; currentNode->next=NULL; //生成新的结点 temp->next=currentNode; temp=currentNode; //结点向下移一位 } temp->next=T->next; //实现单链循环 } } //添加数据 void addList(link T,int *e) { link currentNode=(Node*)malloc(sizeof(Node)); currentNode->data=*e; currentNode->next=NULL; if(!currentNode) { printf("空间申请失败 "); } if(num==0) //如果链表的元素为0 { T->next=currentNode; currentNode->next=currentNode; num++; //链表数量增加 } else //链表不为空时 { link firstNode=T->next; //定义第一个结点 (非头结点) while(firstNode->next!=T->next)//不是尾结点 { firstNode=firstNode->next; //循环到尾结点点 } currentNode->next=T->next; //实现尾结点循环 firstNode->next=currentNode; num++; //链表数量增加 } } //插入数据 void insertList(link T,int i, int *e) { link currentNode=(Node*)malloc(sizeof(Node)); currentNode->data=*e; currentNode->next=NULL; //插入数据的临时结点 if(i<0||i>num+1) { printf("插入的数据不合理 "); } else if(num==0)//链表为空 则i必须为1 { T->next=currentNode; currentNode->next=currentNode; num++; //链表数量增加 } else if(i==num+1) //在尾部添加 { link firstNode=T->next; //定义第一个结点 (非头结点) while(firstNode->next!=T->next)//不是尾结点 { firstNode=firstNode->next; //循环到尾结点点 } currentNode->next=T->next; //实现尾结点循环 firstNode->next=currentNode; num++; //链表数量增加 } else //在链表的中间插入 { //先要找到插入元素的前一个位置 for(int j=0;j<i-1;j++) { T=T->next; } currentNode->next=T->next; T->next=currentNode; num++; //链表数量增加 } } //单循环链表的删除操作 void deleteList(link T,int i) { if(i<1||i>num||num==0) { printf("无法删除 "); } else if(num==1) //链表只有一个元素 { free(T->next); //避免空间泄露 T->next=NULL; num--; //链表长度减少 } else if(i==num) //删除链表的最后一个元素 { link temp=T; //生成临时结点 for(int j=0;j<i-1;j++) { temp=temp->next; //循环到尾结点的前一个结点 } free(temp->next); //避免空间泄露 temp->next=T->next; //指向头结点 num--; //链表长度减少 } else //删除中间结点 { link temp=T; //生成临时结点 for(int j=0;j<i-1;j++) { temp=temp->next; //循环到尾该点的前一个结点 } link deleteNode=temp->next; //指向要删除的节点 temp->next=temp->next->next; free(deleteNode); //避免空间泄露 num--; //链表长度减少 } } //获取元素值 ElemType getElem(link T,int i) { if(i<1||i>num||num==0) { printf("无法获取 "); return -1; } else { for(int j=0;j<i;j++) { T=T->next; //循环到当前结点 } return T->data; } } //打印操作 void printf(link T) { for(int j=0;j<num;j++) { T=T->next; printf("%d ",T->data); } printf(" "); } //销毁操作 void clearList(link T) { link currentNode=T->next; //第一个结点 link temp; while(currentNode->next!=T->next) { temp=currentNode->next; free(currentNode); currentNode=temp; } T->next=NULL; num=0; } int main() { link T; //声明线性表变量 initList(T); int number; //输入指令 int e; //添加的数值 int i; //位置 printf("结束操作-----0 "); printf("链表添加操作-----1 "); printf("链表插入操作-----2 "); printf("链表删除操作-----3 "); printf("链表查找操作-----4 "); printf("链表打印操作-----5 "); printf("链表清空操作-----6 "); printf("你的指令为 "); scanf("%d",&number); while(number!=0) { switch(number) { case 1: //链表添加操作 printf("输入你想要添加的数值"); scanf("%d",&e); addList(T,&e); break; case 2: //链表插入操作 printf("输入你想要插入的数值"); scanf("%d",&e); printf("输入你想要插入第几个位置"); scanf("%d",&i); insertList(T,i,&e); break; case 3: //链表删除操作 printf("输入你想要删除第几个位置"); scanf("%d",&i); deleteList(T,i); break; case 4: //链表查找操作 printf("输入你想要查找第几个位置"); scanf("%d",&i); e=getElem(T,i); printf("第%d个位置的值为: %d ",i,e); break; case 5: //链表打印操作 printf(T); break; case 6: //链表清空操作 clearList(T); printf("单循环链表已删除 "); break; default: printf("你输入的指令不正确 "); } printf("你的下一步指令为 "); scanf("%d",&number); } return 0; }
这些代码的功能我已经一一测试过了,功能没有出现问题,但是可能性能上不太好,代码也不够简练,还是继续加油吧!
遗留下的问题:
例子:void initList(link &T)
为什么链表的创建一定要用上地址&操作符,而剩下的函数实现中不需要用到这地址操作符