(数据结构入门实验C语言版)单向链表的建立与操作,包含去重排序颠倒等操作

这篇博客介绍了如何使用C语言实现链表的各种操作,包括创建链表、遍历、获取元素、计算长度、判断是否为空、排序、去重以及反转链表。去重采用头插法,排序使用冒泡排序,反转链表则通过类似去重的思路。此外,还提供了插入和删除元素的函数。示例代码详细展示了这些功能的实现,便于理解和直接使用。
摘要由CSDN通过智能技术生成

一.前言

对于单向链表,除了常规的建立、插入结点、删除结点、遍历等,此处加入了排序、去重、颠倒等较高级的功能,代码放在下面,比较好理解,可以直接copy运行一下的。实际做实验的时候用不到这么多功能,可以自选几个去用。在这简单对几个函数进行一下说明:

去重:刚开始的时候,用指针p指向链表第一个元素,让Phead->next指向空,这一步实际是把链表一分为二了,再用一个q指向包含头结点的那部分的第一个元素。然后进行循环,每循环一次,p往右走一步,直到走到那部分的尽头。每次循环都做什么呢?每次循环都要检查p此时指向的元素的值和包含头结点那部分的链表有没有重复元素,即设置循环:while(q&&q->data!=p->data)q=q->next;,结局有两个,一是q为null,此时说明没有重复的,利用头插法把p指向的元素插入phead后面,另外一种结局是data相同,此时说明元素重复,则直接free(p)

颠倒:由于去重本质是头插法构造,所以最后元素是反的,那么我们可以再利用“分割链表”这个思想去把元素颠倒过来,所以这个函数的代码与去重几乎一样

排序:这个实际就是一个普通的冒泡排序(当然也可以用其它的)只不过i的初始化相当于p指向第一个元素,i++相当与p=p->next

下面是c语言代码,所有代码为本人手打,如果有错误或不足,还请在评论区指正 ◟̆◞̆♡


二.c代码

前期准备和主函数:

#include<stdio.h>
#include<stdbool.h>
#include<stdlib.h>
typedef struct Node{
	int data;
	struct Node *next;
}Node,*pNode;
pNode CreatList(void);//创建   
void ClearList(pNode);//   
void TraverseList(pNode);//遍历    
int GetElem(pNode,int);//求某个元素的值 
int ListLength(pNode);//求长度 
bool is_empty(pNode);//是否为空 
void SortList(pNode);//排序 (原理:选择排序 
void PurgeList(pNode);//去重 ,本质:头插(缺陷:会使链表颠倒,要么 改为尾插,要么利用颠倒函数 
bool ListDelete(pNode,int);
bool ListInsert(pNode,int,int);//插入元素 
void ListReverse(pNode);//链表翻转,思想为与去重函数类似的分割 ,然后两边指针扫描 
//ClearList,ListDelete,ListInsert的工作指针都是指向目标位置的前驱 ,比如初始把工作指针指向头结点而非第一个元素 
int main()
{
	pNode pHead;
	int i;
	pHead=CreatList();
	TraverseList(pHead);
	printf("请输入您需要第几个元素(数字):");
	scanf("%d",&i);
	printf("第%d个数字为%d\n",i,GetElem(pHead,i)); 
	PurgeList(pHead);
	printf("去重之后链表内容为:\n");
	TraverseList(pHead);
	ListReverse(pHead);
	printf("颠倒之后的链表内容:\n");
	TraverseList(pHead);
	SortList(pHead);
	printf("排序之后链表内容:\n");
	TraverseList(pHead);
	ClearList(pHead);
	printf("清空后的结果:\n");
	if(is_empty(pHead))
	printf("成功清空!\n");
	return 0;
}

函数定义大全: 


pNode CreatList(void)//尾插法 
{
	pNode pHead=(pNode)malloc(sizeof(Node));
	if(pHead==NULL)
	{
		printf("no memory\n");
		exit(1);
	}
	int i,val,len;
	printf("输入您需要的链表长度:");
	scanf("%d",&len);
	pNode pTail=pHead;
	pTail->next=NULL;
	for(i=1;i<=len;i++)
	{
		pNode pNew=(pNode)malloc(sizeof(Node));
		if(pNew==NULL)
		{
			printf("no memory\n");
			exit(1);
		}
		printf("请输入第%d个数据:",i);
		scanf("%d",&val);
		pNew->data=val;
		pTail->next=pNew;
		pNew->next=NULL;
		pTail=pNew;
	}
	return pHead;
}
int ListLength(pNode pHead)
{
	int len=0;
	pNode p=pHead->next;
	while(p)
	{
		len++;
		p=p->next;
	}
	return len;
}
void TraverseList(pNode pHead)
{
	pNode p=pHead->next;
	while(p)
	{
		printf("%d  ",p->data);
		p=p->next;
	}
	printf("\n");
	return;
}
int GetElem(pNode pHead,int i)
{
	pNode p=pHead->next;//指向第一个元素 
	int j=1;
	while(j<i)
	{
		p=p->next;
		j++;
	}
	return p->data;
}
bool is_empty(pNode pHead)
{
	if(pHead->next==NULL)
	return true;
	else 
	return false;
}
void PurgeList(pNode pHead)
{
	pNode p,q,succ;
	p=pHead->next;
	pHead->next=NULL;
	while(p)
	{
		q=pHead->next;
		succ=p->next;
		while(q&&q->data!=p->data)q=q->next;
		if(q==NULL)
		{
			p->next=pHead->next;
			pHead->next=p;
		}
		else free(p);
		p=succ;
	}
	return;
}
void ListReverse(pNode pHead)
{
	pNode p,succ;
	p=pHead->next;
	pHead->next=NULL;
	while(p)
    {
    	succ=p->next;
    	p->next=pHead->next;
    	pHead->next=p;
    	p=succ;
	}
	return;
}
void SortList(pNode pHead)
{
	int i,j,t,len=ListLength(pHead);
	pNode p,q;
	for(i=1,p=pHead->next;i<len;i++,p=p->next)
	{
		for(j=i+1,q=p->next;j<=len;j++,q=q->next)
		{
			if(p->data>q->data)
			{
				t=p->data;
				p->data=q->data;
				q->data=t;
			}
		}
	}
} 
bool ListInsert(pNode pHead,int i,int e)
{
	if(i<=0||i>ListLength(pHead))
	{
		printf("您输入的位置有问题\n");
		return false;
	}
	pNode pNew=(pNode)malloc(sizeof(Node));
	if(pNew==NULL)
	{
		printf("no memory\n");
		return false;
	}
	pNew->data=e;
	pNode p=pHead;
	int j=1;
	while(j<i)
	{
		p=p->next;
		j++;
	}
	pNew->next=p->next;
	p->next=pNew;
	return true;
}
bool ListDelete(pNode pHead,int i)
{
	if(i<=0||i>ListLength(pHead))
	{
		printf("您输入的位置有问题\n");
		return false;
	}
	int j=1;
	pNode p=pHead;
	while(j<i)
	{
		p=p->next;
		j++;
	}
	pNode q;
	q=p->next;
	p->next=q->next;
	free(q);
	return true;
}
void ClearList(pNode pHead)
{
	pNode p;
	p=pHead->next;
	while(p!=NULL)
	{
		pHead->next=p->next;
		free(p);
		p=pHead->next;	
	}
	return; 
}

三. 效果

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值