【C语言代码】链表的简单建立

来源:互联网 发布:linux jar 输出 编辑:程序博客网 时间:2024/05/21 06:25

今天在网上看到链表的建立方法,之前不懂双向链表,循环链表怎么建立,这次一看,觉得方法都通用的,其实就是一种方法,所以把这些分享出来,希望对那些对链表有所惧怕的朋友有所帮助。微笑

这部分链表的建立都是固定长度的,利用三个指针pHead,pNew,pEnd 来构造的,在单向链表和双向链表中,头指针不是有效值,它指向的值才是有效的值,也就是说头指针里面的值一般为空,只有指针域里面有指向下一个结构体的地址;但是循环链表就不能这样了,循环链表中每个指针包括头指针也是有效值的,注意一下。源码都经过测试,可用。

1).下面首先是单向链表的建立方法:

#include<stdio.h>#include<malloc.h>/**************************************************定义了一个结构体类型,并未实际分配内存空间只有定义了变量才分配内存空间**************************************************/struct LNode{int data;struct LNode *next;};/*************************************************创建一个单链表,n为要创建的节点个数,pHead为头指针,没有指向实质数据,只保存第一个节点的地址;pNew 指针总是用来指向新分配的内存空间,pEnd总是指向尾节点,并通过pEnd来链入新增节点。*************************************************/struct LNode *CreatList(int n){int i , a;struct LNode *pHead,*pNew,*pEnd;pHead = NULL;for(i = 1; i <= n; i++){do{pNew = (struct LNode *)malloc(sizeof(struct LNode));}while(pNew == 0);printf("请输入链表中的第%d个数:",i);scanf("%d",&a);pNew->data = a;if(pHead == NULL)/* 指定链表的头指针 */{pHead = pNew;pEnd= pNew;}else{pEnd->next = pNew;pEnd = pNew;}pEnd->next = NULL;/* 尾结点的后继指针为NULL(空) */}return pHead;/*返回链表的头指针*/}void main(){int n;struct LNode *pHead , *p;printf("请输入链表的长度:");scanf("%d",&n);pHead = CreatList(n);/*链表的头指针(head)来标记整个链表*/p = pHead ;printf("\n链表中的数据:");while(p)/*直到结点q为NULL结束循环*/{printf("%d ",p->data);/*输出结点中的值*/p = p->next;/*指向下一个结点*/}}

 2).再者,分享一个双向链表的建立方法,大同小异。

/*题目:创建双向链表程序分析:双向链表的结点有两个指针域,一个指向其直接后继,另一个指向其直接前驱。其中第一个结点的前驱为NULL(头结点为第0个结点),最后一个结点的后继为NULL。代码如下:*/#include <stdio.h>#include <string.h>#include <malloc.h>typedef struct LNode{char name[20];struct LNode *prior,*next;}Lnode;/*双链表的结构定义*/Lnode *CreatList(int n)/*创建双链表函数*/{Lnode *pEnd,*pHead,*pNew;int i;do{pHead = (Lnode *)malloc(sizeof(Lnode));/*动态分配内存赋予头结点*/}while(pHead == 0);pHead->name[0] = '\0';/*为头结点的内容置空*/pHead->prior   = NULL;/*头结点的前驱和后继置为NULL*/pHead->next    = NULL;pEnd = pHead;/*将头结点赋值于p,p总是指向链表的最后一个结点*/for(i = 0; i < n; i++){pNew = (Lnode *)malloc(sizeof(Lnode));/*动态分配内存*/pEnd->next = pNew;/*让p结点的后继指向s*/printf("请输入第%d个同学的名字:",i+1);scanf("%s",pNew->name);pNew->prior = pEnd;/*让s结点的前驱指向p结点*/pNew->next  = NULL;/*让s结点的后继指向NULL,s总是指向新分配的结点*/pEnd = pNew;/*p总是指向链表的最后一个结点*/}pEnd->next = NULL;/*双链表的最后一个结点的后继指向NULL*/return pHead;}Lnode *Search(Lnode *pHead,char *find){Lnode *p = NULL;/*用于定位双链表中的结点*/char *ptemp = NULL;p = pHead->next;while(p){ptemp = p->name;if(strcmp(ptemp,find) == 0)/*strcmp函数比较两个字符串的内容是否相等*/return p ;/*若找到,返回当前结点*/elsep=p->next;/*不相等就继续向下查找*/}printf("信息未找到,重新查找\n");return 0;}void Delete(Lnode *p){if(p->next != NULL)/*确定要删除的结点是否为最后一个结点,最后一个结点后继为NULL*/p->next->prior = p->prior;/*p结点后继的前驱赋予p结点的前驱*/p->prior->next = p->next;/*p结点前驱的后继赋予p结点的后继*/free(p);/*释放p结点的内存空间*/}void Dis(Lnode *p) /*输出双链表*/{while(p){printf("%s ", p->name);p = p->next;}}void main(){int number;char sname[20];Lnode *pHead = NULL ,*sp = NULL;/*head用来标记双链表,sp用来定位结点*/printf("请输入链表的长度:");scanf("%d",&number);pHead = CreatList(number);sp  =  pHead->next;/*sp指向双链表的第一个结点(头结点为第0个结点)*/printf("双链表内的数据为:");Dis(sp);/*输出链表*/printf("\n请输入要查找的学生姓名:");do{scanf("%s",sname);sp = Search(pHead,sname);/*查找链表中的结点*/}while(sp == 0);printf("你想要删除的名字是:%s",sp->name);Delete(sp);/*删除sp结点*/sp = pHead->next;printf("\n现在的双链表是:");Dis(sp);/*输出链表*/printf("\n");}

3).最后分享一个循环链表,希望对大家有所帮助。

/*题目:创建循环链表程序分析:循环链表与普通链表的操作基本一致,只是链表中最后一个结点的指针域指向头结点,是链表形成一个环,从表中的任一结点出发均可找到表中的其它结点在算法中循环遍历链表是判断条件不再是p->next是否为空,而是是否等于链表的头指针。代码如下:*/#include<stdio.h>#include<malloc.h>typedef struct LNode{char num;struct LNode *next;}Lnode;Lnode *CreatList(){Lnode *pNew = NULL,*pEnd = NULL,*pHead;char a;pHead = NULL;/*新创建的链表的头指针为NULL(空)*/a = getchar();while(a != '\n'){pNew = (Lnode *)malloc(sizeof(Lnode));/*动态分配内存空间*/pNew->num = a;/*为结点的数据域赋值*/if(pHead == NULL)/*指定链表的头指针*/pHead = pNew;elsepEnd->next = pNew;/*将新结点p1链入链表*/pEnd = pNew;/*pEnd指向刚链入的新结点,即让pEnd始终指向链表的最后一个结点*/a = getchar();}pEnd->next = pHead;/*链表的最后一个结点的后继指向头结点*/return pHead;}void main(){Lnode *p = NULL,*pHead = NULL;printf("请输入循环链表内容:");pHead = CreatList();p = pHead;printf("\n循环链接表:\n");p = p->next;while(p != pHead){printf("%c",p->num);p = p->next;}printf("\n");}

后面有机会的话还会陆续上传一些链表相关的插入,删除,遍历等程序。

 


0 0