顺序存储---链表的插入与删除。

来源:互联网 发布:淘宝账户怎么修改名字 编辑:程序博客网 时间:2024/05/09 14:49

以下代码在链表创建的基础上实现了对链表数据的插入与删除。
/*以下这个程序实现了非循环链表的数据的插入与删除。(在vc6.0++中调试通过。)链表有几个普及知识点:链表包括:数据域、指针域。头指针:指向头节点的指针。头节点:一个没有数据域的节点。尾指点:没有指针域的节点。ps:对于链表数据的插入一般要借住第三方指针-----尾指针。删除掉一个链表节点之后,一般要将删除的节点的下一节点与它的前一节点相连,要不进行再次输出的时候会出错的。*/# include <stdio.h># include <stdlib.h># include <malloc.h>//定义链表数据类型:数据域、指针域。typedef struct Node{int data;//定义数据域struct Node * pNext;//定义指针域}* pNODE, NODE; //pNODE 即:struct Node *, NODE 即:struct Node.//函数声明----用于对链表的测试pNODE create_list(void);   //这个函数实现创建链表的功能,无需参数,返回头指针。void traverse_list(pNODE); //这个函数通过接收头指针对链表的数据域进行输出。bool is_empty(pNODE);int length(pNODE);void sort_list(pNODE);bool insert_list(pNODE, int , int );//这个函数用于实现在链表的具体位置的前一位进行数据的插入。bool delet_list(pNODE, int ,int *);int main(void){ int len; int pos,val,dval; bool bol; pNODE pHead = NULL;  //定义一个头指针。     pHead = create_list(); /*if(is_empty(pHead)) printf("链表为空\n"); else printf("链表不为空\n");*/ traverse_list(pHead); printf("\n"); len = length(pHead); printf("链表长度为 %d\n",len); printf("请输入你想插入的数据的位置:"); scanf("%d",&pos); printf("请输入你想插入的数据:"); scanf("%d",&val); insert_list(pHead,pos,val);  //sort_list(pHead); traverse_list(pHead); printf("请输入你想删除的数据的位置:\n"); scanf("%d",&pos); bol = delet_list(pHead,pos,&dval); if(bol) { printf("你所删除的数据是%d\n",dval); } else { printf("删除数据失败!\n"); } traverse_list(pHead);return 0;}pNODE create_list(void){int len,val;int i;//动态分配内存单元,大小为链表数据类型大小,并指返回的指针赋值给头指针pHead.pNODE pHead = (pNODE)malloc(sizeof(NODE)); printf("%p\n",pHead);if(NULL == pHead){printf("动态内存分配失败!\n");exit(-1);}//创建一个尾指针 pTail 的目的是:使pTail起一个穿针引线的作用、使次创建的内存块链起来。pNODE pTail = pHead;pTail->pNext = NULL;printf("enter the length  of list  that you want to create !");scanf("%d",&len);for(i=0; i<len ; i++){printf("请输入第 %d 个数据",i+1);scanf("%d",&val);pNODE pNew = (pNODE)malloc(sizeof(NODE));if(NULL == pNew){printf("动态内存申请失败!");exit(-1);}pNew->data = val;pTail->pNext = pNew;pNew->pNext = NULL;pTail = pNew;} printf("%p\n",pHead);return pHead;}//遍历输出链表只需要一个参数:头指针移动最后一个数据为NULL的结点为止。void traverse_list(pNODE pH){pNODE p;p = pH->pNext;while(NULL != p){printf("%d\t",p->data);p = p->pNext;}return;}bool is_empty(pNODE pHead){if(NULL == pHead->pNext)return true;elsereturn false;}int length(pNODE pHead){int len = 0;pNODE p = pHead->pNext;while(NULL != p){len++;p = p->pNext;}return len;}void sort_list(pNODE pHead){int len,temp,i,j;pNODE p,q;len = length(pHead);   //printf("%d",len);//这个地方有必要讲解一下,我在调试时至少发了我一个小时解决当时出现的问题,这里的for循环用了两个变量,其中的i是用来控制对循环次数,//而指针p是用来表示下一个的地址,因为i增加了,链表结点也要跟着移动。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){temp = p->data;p->data = q->data;q->data = temp;}}}return;}bool insert_list(pNODE pHead, int pos, int val){pNODE p =pHead;int i=0;while(NULL !=p && i<pos-1){p=p->pNext;i++;}//这个while函数的功能要说一下,变量i其实是第三方变量,p是头指针,用它来一个一个的往链表的后面移动,移动至需要插入的位置点(pos-1),同时p的数据//也就变成了pos-1的地址了.if(i>pos-1 || NULL == p)return false;pNODE pNew = (pNODE)malloc(sizeof(NODE));printf("%p\n",pNew);if(NULL == pNew){printf("动态内存分配失败!");exit(-1);}pNew->data = val;pNODE pTail = p->pNext;p->pNext = pNew;pNew->pNext = pTail;   //利用尾结点来进行插入,虽然这句话是多余的,但是为了规范还是写上吧。哈。return true;}bool delet_list(pNODE pHead, int pos,int *pval){int i =0;pNODE  p= pHead;while(NULL != p->pNext && i<pos-1) //头节点是不用删除的,因为头节点没有数据域,所以是以p->pNext,即第一个节点进行判断。{p = p->pNext;i++;}if(NULL == p->pNext || i>pos-1) return false;pNODE q = p->pNext;  //这里就是代表的时第pos个位置数据的地址。*pval = p->pNext->data;p->pNext = p->pNext->pNext;//如果没有这句话那么把pos给删除之后,后面的数据就段了。free(q);q = NULL;return true;}