数据结构单链表相关操作

这篇博客介绍了链表数据结构的基础操作,包括创建链表、头部插入、尾部插入、任意位置插入、头部删除、尾部删除、任意位置删除和查找。此外,还讲解了链表排序和反转的功能。代码示例详细展示了每个操作的实现,并提供了主函数示例来演示这些操作的实际应用。
摘要由CSDN通过智能技术生成

首先定义链表数据类型:

typedef int data_t;
typedef struct node{
	data_t data;
	struct node *next;
}link_t;

 打印函数

/*
 * 函数名称:show
 * 函数功能:打印当前列表数据
 * 返回值:若无数据返回-1,有数据返回0
 */
int show(link_t *L){
	if(NULL==L->next){   //健壮性判断
		puts("none data!");
		return -1;
	}
	link_t *temp=L->next;
	while(NULL!=temp){
		printf("%d ",temp->data);
		temp=temp->next;
	}
	puts("");
	return 0;
}

创建链表函数 

/*
 * 函数名称:create
 * 功能:创建列表
 * 返回值:创建失败返回NULL,创建成功返回malloc开辟的首地址。
 */
void *create(void){
	link_t *L=(link_t *)malloc(sizeof(link_t));
	if(NULL==L){
		puts("创建失败!");
		return NULL;
	}
	L->data=-1;
	L->next=NULL;
	return L;
}

  头部插入函数

/*
 * 函数名称:headin
 * 函数功能:输入数据从头部插入
 * 返回值:0
 */
int headin(link_t *L,data_t value){
	link_t *temp=create();
	temp->data=value;
	temp->next=L->next;
	L->next=temp;
	return 0;
}

创建链表,主函数代码如下:

#include "link.c"

int main(int argc, const char *argv[])
{
	link_t *L=create();	
	if(NULL==L){
		return -1;//创建失败退出主函数
	}
	return 0;
}

头部插入

主函数

	while(1){ //循环输入
		data_t i;
		scanf("%d",&i);
		if(-1==i){
			break; //输入-1时退出输出
		}
		headin(L,i);
	}
	show(L);

 头部插入时,最先插入的数据在链表的后面,所以打印时的顺序时相反的。

尾部插入

尾部插入函数

/*
 * 函数名称:tailin
 * 函数功能:输入数据从尾部插入
 * 返回值:0
 */
int tailin(link_t *L,int value){
	link_t *temp=L;
	while(NULL!=temp->next){	//先将指针指向最后一个数据
		temp=temp->next;
	}
	link_t *temp_2=create();
	temp_2->data=value;
	temp_2->next=NULL;
	temp->next=temp_2;
	return 0;
}

尾部插入只需要将主函数中的headin改为tailin,尾部插入,先插入的数据在前,所以打印时时顺序打印。

 任意位置插入数据

/*
 * 函数名称:anyin
 * 函数功能:任意位置插入数据
 * 返回值:成功返回0,失败返回-1
 */
int anyin(link_t *L){
	data_t value;
	int pos,i=0;
	link_t *temp=L->next;
	puts("input postion:");
	scanf("%d",&pos);
    if(0>pos){
		puts("input error");
		return -1;
	}
	while(i<pos){
		if(NULL==temp){		//如果位置越界退出
			puts("postion out link!");
			return -1;
		}
		i++;
		temp=temp->next;
	}
	puts("input data:");
	scanf("%d",&i);
	link_t *temp_2=create();
	temp_2->data=i;
	temp_2->next=temp->next;
	temp->next=temp_2;
	return 0;
}

此处在主函数中先进行了循环尾部插入,然后调用了两次任意位置插入和打印函数,这种插入是在输入位置的后一位插入,如第二次输入,也可以在尾部进行插入。

 头部删除

/*
 * 函数名称:headdel
 * 函数功能:删除链表头部数据
 * 返回值:无数据返回-1,成功返回0
 */
int headdel(link_t *L){
	if(NULL==L->next){	//判断链表是否有数据
		puts("none data!");
		return -1;
	}
	link_t *temp=L->next->next;
	L->next->next=NULL;
	free(L->next);
	L->next=temp;
	return 0;
}

在主函数中还是循环尾部输入,然后调用一次头部删除。

 尾部删除

删除链表尾部的一个数据,上一个链表指向NULL

/*
 * 函数名称:taildel
 * 函数功能:删除尾部数据
 * 返回值:无数据返回-1,成功返回0
 */
int taildel(link_t *L){
	if(NULL==L->next){	//判断链表是否有数据
		puts("none data!");
		return -1;
	}
	link_t *temp=L;
	while(NULL!=temp->next->next){
		temp=temp->next;
	}
	link_t *temp_2=temp->next;
	free(temp_2);
	temp_2=NULL;
	temp->next=NULL;
	return 0;
}

删除后打印结果如下

 任意位置删除

输入位置判断输入是否合法后,删除指定位置的数据。

/*
 * 函数名称:anydel
 * 函数功能:输入位置删除
 * 返回值:位置越界或在最后一位返回-1,成功返回0
 */
int anydel(link_t *L){
	if(NULL==L->next){	//无数据
		puts("none data");
		return -1;
	}
	int pos,i=0;
	link_t *temp=L;
	puts("input postion:");
	scanf("%d",&pos);
    if(0>pos){
		puts("input error");
		return -1;
	}
	while(i<pos){		//要保留删除位的上一位地址,方便指向删除位下一位
		temp=temp->next;
		if(NULL==temp){		//如果位置越界退出
			puts("postion out link!");
			return -1;
		}
		i++;
	}
	if(NULL==temp->next){
		puts("postion out link");
		return -1;
	}
	link_t *temp_2=temp->next;
	temp->next=temp_2->next;
	temp_2->next=NULL;
	free(temp_2);
	temp_2=NULL;
	return 0;
}

在主函数中调用三次,分别删除第一位和最后一位还有最后一个的后一位。

 任意位置查找

/*
 * 函数名称:anyshow
 * 函数功能:查找任意位并打印
 * 返回值:越界返回-1,成功返回0
 */
int anyshow(link_t *L){
	if(NULL==L->next){
		puts("none data!");
		return -1;
	}
	puts("input postion:");
	int pos,i=0;
	link_t *temp=L->next;
	scanf("%d",&pos);
	if(0>pos){
		puts("input error");
		return -1;
	}
	while(i<pos){
		if(NULL==temp){
			puts("out link!");
			return -1;
		}
		temp=temp->next;
		i++;
	}
	if(NULL==temp){
		puts("out link!");
		return -1;		
	}
	printf("data is %d\n",temp->data);
	return 0;
}

 

 

链表数据排序 

此处排序为升序,如果想要降序,只需要把比较时的符号改一下即可

/*
 * 函数名称:rank
 * 函数功能:根据数据大小排序
 * 返回值:一个数据或无数据返回-1,成功返回0
 */
int rank(link_t *L){
	if(NULL==L->next){
		puts("none data");
		return -1;
	}
	if(NULL==L->next->next){
		puts("only noe data");
		return -1;
	}
	link_t *temp=L->next;
	link_t *temp_2=temp->next;
	data_t t;
	while(NULL!=temp->next){
		while(NULL!=temp_2){
			if(temp->data > temp_2->data){
				t=temp->data;
				temp->data=temp_2->data;
				temp_2->data=t;
			}
			temp_2=temp_2->next;
		}
		temp=temp->next;
		temp_2=temp->next;
	}
	return 0;
}

 链表反转

链表中先输入的改到最后面,后输入的改到链表最前面,不是输出,而是链表中相对于表头的位置改变了,并没有出链表。

释放链表

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值