关于链表_1

链表

动态地进行存储的一种结构

其每一个元素节点分为两部分,数据域和指针域

n个节点离散分配,彼此通过指针相连

每个节点都只有一个前驱节点,都只有一个后继结点


专业术语:

头结点

头结点的数据类型和首点的类型一模一样

头结点是首点前面的那个

头结点并不存放有效数据

设置头结点的目的是为了方便对链表的操作 

头指针

存放头结点地址的指针变量即指向头结点的指针变量,下同 

首节点

存放第一个有效数据的结点 

尾节点

存放最后一个有效数据的结点

 

下面举一个例子

例1:

# include <stdio.h>
# include <malloc.h>
# include <stdlib.h>

//定义可一个链表节点的数据类型
struct Node
{
	int data; //8行 数据域
	struct Node * pNext; //9行 指针域
};

//函数声明
struct Node * create_list(void);
void traverse_list(struct Node *);

int main(void)
{
	struct Node * pHead = NULL; //18行 

	pHead = create_list();  //20行
	traverse_list(pHead);   //21行
	
	return 0;
}

struct Node * create_list(void)
{
	int len;  //28行 
	int i;
	int val; //30行 

	struct Node * pHead = (struct Node *)malloc(sizeof(struct Node))//32行
	if (NULL == pHead)
	{
		printf("分配失败, 程序终止!\n");
		exit(-1);
	}
	struct Node * pTail = pHead;
	pTail->pNext = NULL;

	printf("请输入您需要生成的链表节点的个数: len = ");
	scanf("%d", &len);
	
	for (i=0; i<len; ++i)
	{
		printf("请输入第%d个节点的值: ", i+1);
		scanf("%d", &val);
		
		struct Node * pNew = (struct Node *)malloc(sizeof(struct Node));
		if (NULL == pNew)
		{
			printf("分配失败, 程序终止!\n");
			exit(-1);  //终止程序
		}
		pNew->data = val;
		pTail->pNext = pNew;
		pNew->pNext = NULL;
		pTail = pNew;
	}
	
	return pHead;
}

void traverse_list(struct Node * pHead)
{
	struct Node * p = pHead->pNext;

	while (NULL != p)
	{
		printf("%d  ", p->data);
		p = p->pNext;
	}
	printf("\n");
	
	return;
}

输出结果为:


当输入一个整数数字时(假设为3),则会提示输入要存储的整数,请输入第1个节点的值:,然后输入一个整数数字,接着就是输入第二个、第三个,最终是将输入的数字保存在链表中并输出


对于链表,一个元素(节点)分为数据域和指针域,数据域存储数据,指针域存储下一个元素的地址

本程序中,第8行和第9行表示的就是一个元素的数据域和指针域,而它们所在的结构体表示链表中的一个元素;而第18行的pHead则是用来存放链表头结点的地址;第20行 create_list() 的功能是:创建一个非循环单链表,并将该链表的头结点的地址付给pHead,第21行是将链表输出,traverse的意思就是遍历,而遍历的意思是依次访问每个节点,这里可以理解为输出

接下来,28行和30行分别表示“存放有效节点的个数”和“临时存放用户输入的结点的值”;32行是分配了一个不存放有效数据的头结点

对了,还要说的是一个关键字typedef,这是个类型别名,具体用法见下例

例2:

# include <stdio.h>

int main(void)
{
	typedef int LISI;
	LISI i= 0;  //等价于int i = 0;
	
	printf("%d\n", i); 
	
	return 0;
}

输出结果为:



由上可知typedef是为int再多取一个名字字(这里是LISI),在以下的代码里而LISI和int,用哪个都行,这么做为的是简单,当然,上面那个程序看不到什么简单,下面再举一个例子

例3:

# include <stdio.h>

typedef struct student
{
	int sid;
	char name[100];
	char sex;	
}ST;

int main(void)
{
	struct student a;
	ST s;    
	a.sid = 333;
	s.sid = 100;
	printf("%d %d\n",a.sid, s.sid); 
	
	return 0;
}

输出结果为:


由上可知,ST等价于struct student

如果将ST变为* PST,则* PST等价于struct student *

另外,这样写也可以

typedef struct student
{
    int sid;
    char name[100];
    char sex;
}ST, *PST;

这时同时声明了ST和* PST两个类型

需要说明的是,ST和PST这样的名字可以随便取(只要不是关键字),但一般都大写


【所有代码均在windows系统下C-Free5.0下运行通过】

(如有错误,敬请指正)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值