单循环链表的初始化、插入、删除、遍历、查找

来源:互联网 发布:摄影入门推荐知乎 编辑:程序博客网 时间:2024/05/13 04:36
#include <stdio.h>#include <stdlib.h>#include <conio.h>typedef struct CLinkList{int data;struct CLinkList *next;}node;void ds_init(node **pNode);//初始化循环链表void ds_insert(node **pNode, int i);//插入结点void ds_delete(node **pNode, int i);//删除结点void ds_traverse(node *pNode);//遍历int  ds_search(node *pNode, int elem);//返回结点所在的位置int main(void){node *pHead = NULL;char opp = 0;int find;while( opp != '0'){printf("1.初始化链表\n2.插入结点\n3.删除结点\n\4.遍历链表\n5.返回结点位置\n0.退出\n请选择你的操作:");scanf("%c", &opp);switch( opp ){case '1':ds_init(&pHead);printf("\n");ds_traverse(pHead);printf("\n");break;case '2':printf("输入需要插入结点的位置:");scanf("%d", &find);ds_insert(&pHead, find);printf("在位置%d插入值后:\n", find);ds_traverse(pHead);printf("\n");break;case '3':printf("输入需要删除结点的位置:");scanf("%d", &find);ds_delete(&pHead, find);printf("删除第%d个结点后:\n", find);ds_traverse(pHead);printf("\n");break;case '4':ds_traverse(pHead);printf("\n");break;case '5':printf("你要查找的结点的值:");scanf("%d", &find);ds_traverse(pHead);printf("元素%d所在位置:%d\n", find, ds_search(pHead, find) );printf("\n");break;case '0':exit(0);}}getch();return 0;}void ds_init(node **pNode)//初始化循环链表{int count = 1;int item;node *temp;node *target;printf("输入结点的值,输入0完成初始化\n");while( 1 ) {printf("第%d项:", count ++);scanf("%d", &item);fflush(stdin);//清除缓冲区if(item == 0)return;if( (*pNode) == NULL )//只有一个结点{*pNode = (node *)malloc( sizeof(struct CLinkList) );if( !(*pNode) )exit(0);(*pNode)->data = item;(*pNode)->next = *pNode;}else{//找到最后一个结点for(target = (*pNode); target->next != (*pNode);target = target->next);temp = (node  *)malloc( sizeof(struct CLinkList) );if( !temp )exit(0);temp->data = item;temp->next = *pNode;target->next = temp;}}}void ds_insert(node **pNode, int i)//插入结点{node *temp;node *target;int item;int j = 1;printf("输入要插入结点的值:");scanf("%d", &item);temp = (node *)malloc( sizeof(struct CLinkList) );if( !temp )exit(0);if(i == 1){temp->data = item;temp->next = (*pNode);for(target = (*pNode);target->next != (*pNode);target = target->next);target->next = temp;*pNode = temp;}else{target = *pNode;for( ;j < i-1;j ++)target = target->next;temp->data =item;temp->next = target->next;target->next = temp;}}void ds_delete(node **pNode, int i) //删除结点{node *target;node *temp;int j = 1;if(i == 1){for(target = *pNode;target->next != *pNode;target = target->next);temp = *pNode;*pNode = (*pNode)->next;//!!!!target->next = *pNode;free(temp);}else{target = *pNode;for( ;j < i-1;j ++ )target = target->next;temp = target->next;target->next = temp->next;free(temp);}}void ds_traverse(node *pNode) //遍历{node *temp;temp = pNode;printf("***********链表中的元素******************\n");#if (0)while(temp->next != pNode){printf("%4d", temp->data);temp = temp->next;}printf("%4d", temp->data);#endifdo{printf("%d  ", temp->data);}while( (temp = temp->next) != pNode );printf("\n");}int ds_search(node *pNode, int elem) //返回结点所在的位置{node *target;int i = 1;for(target = pNode;target->data != elem && target->next != pNode; ++i)target = target->next;if(target->next == pNode){if(target->data != elem)return 0;else return 1;}elsereturn i;}


写的时候犯了几个错误

1、opp木有赋初值

2、在插入结点函数后,我修改成,先为temp开辟内存,再判断链表有几个结点。

原代码

    if(i == 1){ //新插入的结点作为第一个结点        temp = (node *)malloc(sizeof(struct CLinkList));if(!temp)            exit(0);temp ->data = item;        /*寻找到最后一个结点*/        for(target = (*pNode); target->next != (*pNode); target = target->next);temp->next = (*pNode);        target->next = temp;        *pNode = temp;    }    else{        target = *pNode;        for( ; j < (i-1); ++j ){target=target->next;}temp = (node *)malloc(sizeof(struct CLinkList));if(!temp)            exit(0);temp ->data = item;        p = target->next;        target->next = temp;        temp->next = p;    }

修改后

temp = (node *)malloc( sizeof(struct CLinkList) );if( !temp )exit(0);if(i == 1){temp->data = item;temp->next = (*pNode);for(target = (*pNode);target->next != (*pNode);target = target->next);target->next = temp;*pNode = temp;}else{target = *pNode;for( ;j < i-1;j ++)target = target->next;temp->data =item;temp->next = target->next;target->next = temp;}

这里的else内,用

temp->data =item;temp->next = target->next;target->next = temp;
代替

temp ->data = item;        p = target->next;        target->next = temp;        temp->next = p;
语句和变量更少


3、在删除结点的函数中,当删除第一个结点时用了
temp = *pNode;        target->next = (*pNode)->next;        free(temp);
各种崩溃,原因是头结点错了

后来改为
temp = *pNode;        *pNode = (*pNode)->next;        target->next = *pNode;        free(temp);
就好了

4、在遍历函数中
一开始循环函数用成了
while(temp->next != pNode){printf("%4d", temp->data);temp = temp->next;}
发现少了最后一个结点值,当temp为最后一个结点时,直接退出了循环,没有进行输出
后来想到了俩办法
#if (0)while(temp->next != pNode){printf("%4d", temp->data);temp = temp->next;}printf("%4d", temp->data);#endifdo{printf("%d  ", temp->data);}while( (temp = temp->next) != pNode );printf("\n");
一个办法是当退出循环后再输出一次,还有一个办法是用do while。

5、查找结点函数中
原函数
int ds_search(node *pNode, int elem){    node *target;    int i = 1;    for(target = pNode; target->data != elem && target->next != pNode; ++i){target = target->next;}if(target->next == pNode) /*表中不存在该元素*/        return 0;    else        return i;}
后来赶脚有点小问题,当只有一个结点的时候,会返回0而不是返回1。
在if语句中再添加一个if语句,酱紫就好了
if(target->next == pNode){if(target->data != elem)return 0;else return 1;}elsereturn i;


最后有一个问题木有解决。。
就是再次初始化循环链表的时候,会在原来的基础上继续添加结点。。。而不是重新初始化结点。。
 
一个简单的办法就是改成:
case '1':pHead = NULL;ds_init(&pHead);printf("\n");ds_traverse(pHead);printf("\n");break;

尴尬只是酱紫的话会内存泄漏。。。
大笑所以还是把结点一个个释放吧

生气最后放粗最终版本

#include <stdio.h>#include <stdlib.h>#include <conio.h>typedef struct CLinkList{int data;struct CLinkList *next;}node;void ds_init(node **pNode);//初始化循环链表void ds_insert(node **pNode, int i);//插入结点void ds_delete(node **pNode, int i);//删除结点void ds_traverse(node *pNode);//遍历int  ds_search(node *pNode, int elem);//返回结点所在的位置void ds_deleteall(node **pNode);//删除所有结点int main(void){node *pHead = NULL;char opp = 0;int find;while( opp != '0'){printf("1.初始化链表\n2.插入结点\n3.删除结点\n\4.遍历链表\n5.返回结点位置\n0.退出\n请选择你的操作:");fflush(stdin);//清除缓冲区scanf("%c", &opp);switch( opp ){case '1':ds_deleteall(&pHead);ds_init(&pHead);printf("\n");ds_traverse(pHead);printf("\n");break;case '2':printf("输入需要插入结点的位置:");scanf("%d", &find);ds_insert(&pHead, find);printf("在位置%d插入值后:\n", find);ds_traverse(pHead);printf("\n");break;case '3':printf("输入需要删除结点的位置:");scanf("%d", &find);ds_delete(&pHead, find);printf("删除第%d个结点后:\n", find);ds_traverse(pHead);printf("\n");break;case '4':ds_traverse(pHead);printf("\n");break;case '5':printf("你要查找的结点的值:");scanf("%d", &find);ds_traverse(pHead);printf("元素%d所在位置:%d\n", find, ds_search(pHead, find) );printf("\n");break;case '0':exit(0);}}getch();return 0;}void ds_init(node **pNode)//初始化循环链表{int count = 1;int item;node *temp;node *target;printf("输入结点的值,输入0完成初始化\n");while( 1 ) {printf("第%d项:", count ++);scanf("%d", &item);fflush(stdin);//清除缓冲区if(item == 0)return;if( (*pNode) == NULL )//只有一个结点{*pNode = (node *)malloc( sizeof(struct CLinkList) );if( !(*pNode) )exit(0);(*pNode)->data = item;(*pNode)->next = *pNode;}else{//找到最后一个结点for(target = (*pNode); target->next != (*pNode);target = target->next);temp = (node  *)malloc( sizeof(struct CLinkList) );if( !temp )exit(0);temp->data = item;temp->next = *pNode;target->next = temp;}}}void ds_insert(node **pNode, int i)//插入结点{node *temp;node *target;int item;int j = 1;printf("输入要插入结点的值:");scanf("%d", &item);temp = (node *)malloc( sizeof(struct CLinkList) );if( !temp )exit(0);if(i == 1){temp->data = item;temp->next = (*pNode);for(target = (*pNode);target->next != (*pNode);target = target->next);target->next = temp;*pNode = temp;}else{target = *pNode;for( ;j < i-1;j ++)target = target->next;temp->data =item;temp->next = target->next;target->next = temp;}}void ds_delete(node **pNode, int i) //删除结点{node *target;node *temp;int j = 1;if(i == 1){for(target = *pNode;target->next != *pNode;target = target->next);temp = *pNode;*pNode = (*pNode)->next;//!!!!target->next = *pNode;free(temp);}else{target = *pNode;for( ;j < i-1;j ++ )target = target->next;temp = target->next;target->next = temp->next;free(temp);}}void ds_traverse(node *pNode) //遍历{node *temp;temp = pNode;printf("***********链表中的元素******************\n");#if (0)while(temp->next != pNode){printf("%4d", temp->data);temp = temp->next;}printf("%4d", temp->data);#endifdo{printf("%d  ", temp->data);}while( (temp = temp->next) != pNode );printf("\n");}int ds_search(node *pNode, int elem) //返回结点所在的位置{node *target;int i = 1;for(target = pNode;target->data != elem && target->next != pNode; ++i)target = target->next;if(target->next == pNode){if(target->data != elem)return 0;else return 1;}elsereturn i;}void ds_deleteall(node **pNode)//删除所有结点{int count = 0, i;node *temp;node *target;if( (*pNode) == NULL )return ;for(target = *pNode; target->next != *pNode;target = target->next)count ++ ;for(i = 0;i < count;i++){temp = *pNode;*pNode = (*pNode)->next;target->next = *pNode;free(temp);}free(target);*pNode = NULL;}


原创粉丝点击