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

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

这部分链表的建立都是固定长度的,利用三个指针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 ;					/*若找到,返回当前结点*/
		else
			p=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;
		else
			pEnd->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");
}

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

 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

笨鸟快飞呀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值