单链表操作,创建,遍历,插入,删除,排序等操作
2015-03-01 21:02
555 查看
<pre name="code" class="cpp">#include <stdio.h> #include <malloc.h> #include <stdlib.h> #include <stdbool.h> /* typedef enum c_bool{ false = 0, true = 1, }bool;*/ //由于c当中没有布尔类型,只能够通过枚举来定义了or通过头文件<stdbool.h>也可以 typedef struct Node{ int data; struct Node * pNext; }NODE, *PNODE; //NODE相当于 struct Node 和 PNODE相当于struct Node * 类型 PNODE create_list(); void traverse_list(PNODE pHead); bool is_empty(PNODE pHead); bool insert_list(PNODE pHead,int pos,int val); //pos从1开始 int length_list(PNODE pHead); bool delete_list(PNODE pHead,int pos,int * pVal); void sort_list(PNODE pHead); int main(void){ PNODE pHead = NULL; int pos; //要插入的位置 int v; pHead = create_list(); traverse_list(pHead); printf("请输入要插入的位置:"); scanf("%d",&pos); printf("请输入要插入的数字:"); scanf("%d",&v); insert_list(pHead,pos,v); traverse_list(pHead); printf("插入后数组的长度为:%d\n",length_list(pHead)); printf("请输入要删除的位置:"); scanf("%d",&pos); if(delete_list(pHead,pos,&v)){ printf("您删除的元素是:%d\n",v); } else{ printf("删除失败!\n"); } traverse_list(pHead); sort_list(pHead); printf("逆序排列后\n"); traverse_list(pHead); return 0; } PNODE create_list(){ int len; //链表长度 int val; //具体的数值 int i; //循环用到的变量 PNODE pNew; //新插入的节点 PNODE pTail; //尾节点 printf("请输入要创建链表的长度:"); scanf("%d",&len); PNODE pHead = (PNODE)malloc(sizeof(NODE)*len); if (pHead==NULL) { printf("内存分配失败\n"); exit(-1); } pTail = pHead; pTail->pNext = NULL; for (i=0;i<len;i++) { printf("输入第%d个数为:",i+1); scanf("%d",&val); PNODE pNew = (PNODE)malloc(sizeof(NODE)); if (pNew == NULL){ printf("内存分配失败\n"); exit(-1); } pNew->data = val; pTail->pNext = pNew; pNew->pNext = NULL; pTail = pNew; //这里是通过这样一种思想,考虑有一个尾节点存在,然后新结构体指针 //始终挂在尾节点的后面,然后把新结构体指针清零,让尾节点指向新的结构体指针,这样就 // 能够保证尾节点始终指向最后了,循环几次就是依次在尾节点上添加了 /*这样是添加不进去的 这样就要为每个节点分配不同指针变量了 pHead->data = val; pHead->pNext = pHead;*/ } /*应该用循环来解决问题的 printf("输入第2个数为:"); scanf("%d",&val); pHead->data = val;*/ return pHead; } void traverse_list(PNODE pHead){ int i; int cnt; PNODE p = pHead; //下面可以直接用p变量来代替一长串指针 ,p是指向当前元素 //也可以p=pHead->pNext printf("请输入要显示几个数字:"); scanf("%d",&cnt); for(i=0;i<cnt;i++){ printf("%d",p->pNext->data); p = p->pNext; printf("\t"); } printf("\n"); return; } bool is_empty(PNODE pHead) { if (NULL == pHead->pNext) return true; else return false; } bool insert_list(PNODE pHead,int pos,int val){ int i=0; PNODE p = pHead; //这里如果改成p=pHead 下面我就不知道该怎么改了,不懂?以后调试再看看吧 while (NULL!=p && i<pos-1)//把头指针向后移动pos-1个,或者到空 { p = p->pNext; ++i; } //循环之后p就指向了第pos-1个,也就是pos之前的那个元素了 if (i>pos-1 || NULL==p) //这小段我不知道干嘛用,不是前面都循环判断了么,为了防止意外? return false; PNODE pNew = (PNODE)malloc(sizeof(NODE)); pNew->data = val; pNew->pNext = p->pNext; p->pNext = pNew; /* 这是另一种方法,和上面那种是等效的 PNODE q = p->pNext; p->pNext = pNew; pNew->pNext = q;*/ return true; } int length_list(PNODE pHead){ PNODE p = pHead->pNext; int length = 0; while(p != NULL){ length++; p = p->pNext; } return length; } bool delete_list(PNODE pHead,int pos,int *pVal){ int i = 0; PNODE p = pHead; //这里为什么不能写成p= pHead->next ?因为这样就直接指向下一个元素了,要始终保持P指向要删除的前一个元素? while(p!=NULL && i<pos-1){ p = p->pNext; i++; } if (i>pos-1 || p==NULL) return false; PNODE q = p->pNext; *pVal = q->data; //指针指向被删除元素的数值 p->pNext = q->pNext; free(q); //释放掉被删除的节点 q = NULL; //p->pNext = q->pNext; 直接写成这样内存容易溢出,被删除的那个值依然占着内存 return true; } //排序部分和普通的数组排序基本可以套用进去的,广义的算法是一样的 void sort_list(PNODE pHead){ PNODE p,q; int len = length_list(pHead); int i, j, t; for(i=0,p=pHead->pNext; i<len-1; i++,p=p->pNext){ for(j=i+1,q=p->pNext;j<len;j++,q=q->pNext){ if(p->data < q->data){ t = p->data; p->data = q->data; q->data = t; } } } return; }
总结:
1.学会如何单链表的基本操作
2.在编译调试中遇到很多问题,学会分析并且解决问题
3.理解链路头指针存在的好处,对于临时变量p的应用在删除和插入中有点不太理解,其他地方都可以灵活运用指向下一个还是直接指向头指针,在后面调试当中慢慢再琢磨吧,那个循环判断也不是很理解pos-1的指向,为什么这样编写,不懂?
以上基本上是本次学习链表的收获,学习数据结构的第一个程序,花了近6个小时,也体会到了编程之美,之前自己都没有好好静下心来编写代码,看懂,听懂和自己编写成功运行是完全两个概念所以必须要动手,调试,运行。。。。。
相关文章推荐
- 单链表创建-遍历-排序-插入-删除-逆序操作
- c语言实现单链表的操作:创建,删除,插入,反转, 排序等
- 数据结构顺序表的操作全集(创建,遍历,插入,删除,排序等等)
- C++单链表的动态创建,查找,遍历,删除,插入,添加,排序
- C++ 单链表的建立,插入数值,删除数值,排序,遍历,和分割操作
- 单链表的常用操作,包括单链表的创建、插入、删除、排序、逆置以及打印输出等
- C语言单链表的创建、插入、查找、删除、求长、排序、遍历
- C++单链表的操作(创建,删除,打印,遍历,插入)
- 单链表的创建删除排序插入逆向打印各种操作
- 单链表的基本操作(创建、删除、插入、遍历)
- 数据结构——单链表的创建、删除、遍历以及节点的插入、删除等操作
- 单链表的创建、遍历、插入、删除、查找、逆转
- 笔试题:创建一个单链表,结点包含学生的学号,姓名,性别,年龄信息.写几个程序,实现按学生学号插入,查询,删除等操作.
- 链表的基础操作总结(链表创建,插入,删除,遍历等等)
- 链表初解(一)——单链表的创建、删除、插入、测长、排序、逆置
- 程序员面试宝典(第三版)——单链表的基本操作:建立,求长度,输出,排序,插入,删除,逆置
- 单链表的创建、计数打印、删除与插入操作
- 写给初学数据结构的同学之(循环双链表基本操作,创建,插入,删除,排序)
- 不疯魔,不成活!——单链表的创建,插入,删除等操作
- 单链表的创建、插入、删除、倒置操作