数据结构 用C语言创建链表 对链表的基本操作

如何用C语言创建链表

链表使线性表的一种,比起顺序表,链表可以根据需要改变自身的大小,动态分配内存,比循序表更灵活。这里介绍我用c语言实现链表基本操作的方法。

#include<stdio.h>
#include<malloc.h>//调用malloc
#pragma warning(disable:4996) //防止scanf(),printf报错

定义一个结构体,用来储存链表的节点:

typedef struct node {
	int data = 0;
	node* next = NULL;
}Node, * PNode;

定义一个结构体,存放指向表头和表尾的指针,同时用于记录链表的长度:

typedef struct linkedlist {
	PNode head = NULL;
	PNode tail = NULL;
	int length = 0;
}Llist;

定义函数,用于实现以下功能

Llist init_list();					//创建一个链表
Llist append_list(Llist llist);		//在链表最后插入一个结点
Llist ins_node(Llist llist);		//在链表指定位置中插入一个结点
Llist del_node(Llist llist);		//删除链表指定位置处的一个节点
void print_list(Llist llist);		//打印整段链表

创建链表的过程中,思路是这样的:先malloc一块内存,令head指针和tail指针都指向这块内存空间,再令这块内存的next指向NULL,输入第一个值,完成第一个结点的创建。若表长大于1,则不断调用appen_list()函数,增长链表的长度。实现如下:

Llist init_list() {
	Llist llist;
	int length;
	//Create list head
	llist.head = llist.tail=(PNode)malloc(sizeof(Node));
	printf("Enter the length :");
	scanf("%d", &length);
	printf("Enter the 1 node:");
	scanf("%d", &llist.head->data);
	llist.length++;
	llist.head->next = NULL;
	//append other node
	for (; llist.length < length;)
		llist = append_list(llist);//函数实现见下放
	return llist;
}

append_list()函数实现过程如下:

Llist append_list(Llist llist) {
	PNode node = (PNode)malloc(sizeof(Node));//申请一块新内存
	printf("Enter the %d node:", llist.length + 1);
	scanf("%d", &node->data);
	node->next = NULL;		//因为在尾部,使新内存的next指向NULL
	llist.tail->next = node;//令原链表的尾结点指向新申请出来的结点
	llist.tail = node;		//尾节点指向新申请的结点
	llist.length++;			//表长度加一
	return llist;
}

创建完一段链表后,我们写一个print_list函数将他打印出来:

void print_list(Llist llist) {
	PNode pos;//定义position,从头结点开始遍历所有结点
	printf("**************************************************\n");
	for (pos = llist.head; pos; pos = pos->next)
		printf("%d\t",pos->data);
	printf("\n**************************************************\n");
}

删除结点的函数实现:

Llist del_node(Llist llist) {
	int Dpos;//输入删除的位置,存在Dpos处
	PNode pos1 = (PNode)malloc(sizeof(Node));
	pos1 = llist.head;//结点pos1,令其等于头结点
		PNode pos2 = pos1->next;//结点pos2指向pos1后面的位置
		printf("Enter the delete position:");
	scanf("%d", &Dpos);if(!(Dpos <= llist.length))		//若位置不小于表长,报错
		printf("position false");
	//若要删除第一个结点(头节点),令头节点指向其下一个位置,在free掉原来第一个结点
	if (Dpos == 1) {
		llist.head = llist.head->next;
		free(pos1);
		pos1 = llist.head;
	}
	//删除其他结点,需要遍历链表,并设置一个计数器,记录pos1和pos2移动了多少位置
	else {
		for (int cnt = 1; cnt < Dpos - 1; cnt++) {
			pos1 = pos1->next;
			pos2 = pos1->next;
		}
		//当pos2指向要删除的位置时,令pos1指向pos2后面的位置,再free掉pos2,便把该结点删除了
		pos1->next = pos2->next;
		free(pos2);
	}
	llist.length--;//删除一个结点,表长减一
	return llist;
	
}

插入结点的实现:

Llist ins_node(Llist llist) {
	int Ipos;
	PNode pos = llist.head;						//用于遍历链表,找到插入位置
	PNode node = (PNode)malloc(sizeof(Node));	//新的结点
	printf("Enter the insert position:");
	scanf("%d", &Ipos);
	if (!(Ipos <= llist.length))			//若插入位置不小于表长,报错
		printf("position false!\n");
	printf("Enter the value:");
	scanf("%d", &node->data);
	if (Ipos == 1) {						//若在第一个位置插入结点
		node->next = llist.head;			//令新结点指向原表头
		llist.head= node;					//再让新结点成为表头
	}
	else {
		for (int cnt = 1; cnt < Ipos - 1; cnt++)//遍历链表,直到要插入的位置
			pos = pos->next;
		node->next = pos->next;				//令新结点指向当前结点的后一个结点
		pos->next = node;					//再令当前结点指向新结点
	}
	llist.length++;							//表长增长
	return llist;
}

用main()函数过一遍前面的函数

int main()
{
	Llist llist = init_list();	//initialization a linked list
	llist = del_node(llist);	//delete a listnode
	print_list(llist);
	llist = ins_node(llist);	//insert a listnode
	print_list(llist);
	printf("the length of list:%d\n", llist.length);

	return 0;
}

得到结果:在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值