数据结构:单向链表的操作

1)预处理

#ifndef  __HEAD1_H__
#define  __HEAD1_H__

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

typedef char datatype;

typedef struct Node
{
	union{
		//数据域
		int len;
		datatype data;
	};
	//指针域:存储下一个节点的地址
	struct Node* next;
}*Linklist;


Linklist Create_head();
Linklist Create_Node();
void Insert_head(Linklist L,datatype e);
void Output(Linklist L);
void Insert_rear(Linklist L,datatype e);
void Delete_head(Linklist L);
void Delete_rear(Linklist L);
int Insert_pos(Linklist L,int pos,datatype e);
int Delete_pos(Linklist L,int pos);
int Search_pos(Linklist L,int pos);
int Revise_pos(Linklist L,int pos,datatype e);
Linklist Search_data(Linklist L,datatype e);
int Revise_data(Linklist L,datatype e,datatype k);
int Delete_data(Linklist L,datatype e);
int Insert_data(Linklist L,datatype e,datatype k);
void LinklistRev(Linklist L);
void LinklistSort(Linklist L);
void Free(Linklist L);


#endif

2)函数声明

#include"head1.h"

//堆区头节点创建申请空间
Linklist Create_head()
{ 
	Linklist L=(Linklist)malloc(sizeof(struct Node));
	if(L==NULL)
		return NULL;
	//头节点创建成功
	L->len=0;     	//数据域
	L->next=NULL; 	//指针域
	return L; 
}

//创建普通节点申请空间
Linklist Create_Node()
{
	Linklist p=(Linklist)malloc(sizeof(struct Node));
	if(p==NULL)
		return NULL ;
	//普通节点创建成功
	p->data=0; //新节点的数据域清0
	p->next=NULL;//新节点指针域为空
	return p;
}

//头插
void Insert_head(Linklist L,datatype e)
{
	if(L==NULL)
	{
		printf("头插失败\n");
		return ;
	}
	Linklist p=Create_Node();
	if(p==NULL)
		return ;
	//节点创建成功
	p->data=e;//为新节点数据域复制
	p->next=L->next;
	L->next=p;
	L->len++;
}

//单链表遍历
void Output(Linklist L)
{
	//遍历条件:判断链表是否创建,链表是否为空
	if(L==NULL||L->len==0)
	{
		printf("遍历失败");
		return ;
	}
	Linklist p=L;
#if 0
	fot(int i=0;i<L->len;i++)
	{
		p=p>next;
		printf("%c\t",p->data);
	}
#else
	while(p->next!=NULL) 	//while(p->next)
	{
		p=p->next;
		printf("%c\t",p->data);
	}
#endif
	putchar(10);
}

//尾插
void Insert_rear(Linklist L,datatype e)
{
	if(L==NULL)
	{
		printf("头插失败\n");
		return ;
	}
	//创建新节点
	Linklist p=Create_Node();
	if(p==NULL)
		return ;
	//找到最后一个节点
	Linklist s=L;
	while(s->next)
	{
		s=s->next;
	}
	//把新节点插入到最后一个节点的后面
	p->data=e ;
	s->next=p ;
	L->len++;
}

//头删:删除头结点的后继节点
void Delete_head(Linklist L)
{
	//判段链表是否为空,链表创建是否成功
	if(L==NULL||L->next==NULL)
		return;
	//删除
	Linklist p=L->next;
	L->next=p->next;
	free(p);
	p=NULL;
	L->len--;
}

//尾删:删除最后一个节点
void Delete_rear(Linklist L)
{
	//判段链表是否为空,链表创建是否成功
	if(L==NULL||L->next==NULL)
	{
		printf("尾删失败\n");
		return ;
	}
	//找到倒数第二个节点 
	Linklist p=L;
	for(int i=0;i<L->len-1;i++)
	{
		p=p->next;
	}	
	//释放最后一个节点
	free(p->next);
	p->next=NULL;
	L->len--;
}

//按位置插入
int Insert_pos(Linklist L,int pos,datatype e)
{
	//判断链表是否创建,链表是否为空,位置是否合理	
	if(L==NULL ||L->next==NULL ||pos<1 || pos>L->len+1)
	{
		printf("插入失败\n");
		return -1;
	}
	//找到pos-1位置,起名字p
	Linklist p=L;//p从头节点开始向后遍历
	for(int i=0;i<pos-1;i++)
	{
		p=p->next;//向后移动
	}
	//在p和p->next之间插入新节点s
	Linklist s=Create_Node();
	if(s==NULL)
	{
		printf("新节点创建失败\n");
		return -1;
	}
	//s的数据域
	s->data=e;
	//s的指针域
	s->next=p->next;
	p->next=s;
	L->len++;
	return 0;
}

//按位置删除
int Delete_pos(Linklist L,int pos)
{
	//判断位置删除的条件:单链表是否创建,是否为空,位置是否合理
	if(L==NULL ||L->next==NULL ||pos<1 || pos>L->len+1)
	{
		printf("删除失败\n");
		return -1;
	}
	//找到pos-1位置,起名字p
	Linklist p=L;
	for(int i=0;i<pos-1;i++)
	{
		p=p->next;//向后移动
	}
	Linklist s=p->next;
	p->next=s->next;
	free(s);
	s=NULL;
	L->len--;
	return 0;
}

//按位置查找
int Search_pos(Linklist L,int pos)
{
	//判断位置查找的条件:单链表是否创建,是否为空,位置是否合理
	if(L==NULL ||L->next==NULL ||pos<1 ||pos>L->len+1)
	{
		printf("查找失败\n");
		return -1;
	}
	Linklist p=L;
	for(int i=0;i<pos-1;i++)
	{
		p=p->next;//向后移动
	}
	printf("查找到的元素是:%c\n",p->data);	

}

//按位置修改
int Revise_pos(Linklist L,int pos,datatype e)
{
	//判断位置修改的条件:单链表是否创建,是否为空,位置是否合理
	if(L==NULL ||L->next==NULL ||pos<1 ||pos>L->len+1)
	{
		printf("修改失败\n");
		return -1;
	}
	Linklist p=L;
	for(int i=0;i<pos;i++)
	{
		p=p->next;
	}
	p->data=e;
	return 0;
}

//按元素查找
Linklist Search_data(Linklist L,datatype e)
{
	if(L==NULL||L->next==NULL)
	{
		printf("查找失败\n");
		return NULL;
	}
	Linklist p=L;
	for(int i=1;i<=L->len;i++)
	{
		p=p->next;
		if(p->data==e)
		{
			printf("%c在链表中\n",p->data);
			return p;
		}
	}
	return NULL;
}

//按元素修改
int Revise_data(Linklist L,datatype e,datatype k)
{
	Linklist p=Search_data(L,e);
	if(p==NULL)
	{
		printf("%c不存在,修改失败\n",e);
		return -1;
	}
	p->data=k;
	Output(L);
	return 0;
}

//按元素删除
int Delete_data(Linklist L,datatype e)
{
	if(L==NULL||L->next==NULL)
	{
		printf("删除失败\n");
		return -1;
	}
	Linklist p=L;
	//查找e是否存在
	for(int i=1;i<=L->len;i++)
	{
		p=p->next;
		if(p->data==e)
		{
			Delete_pos(L,i);
			printf("删除后的链表为:\n");
			Output(L);
			return 0;
		}
	}
	printf("删除失败\n");
	return -1;
}

//单链表在制定元素前插入
int Insert_data(Linklist L,datatype e,datatype k)
{
	if(L==NULL||L->next==NULL)
	{
		printf("插入失败\n");
		return -1;
	}
	Linklist p=Search_data(L,e);
	for(int i=1;i<L->len;i++)
	{
		p=p->next;//向后移动
	}
	//在p和p->next之间插入新节点s
	Linklist s=Create_Node();
	if(s==NULL)
	{
		printf("新节点创建失败\n");
		return -1;
	}
	//s的数据域
	s->data=k;
	//s的指针域
	s->next=p->next;
	p->next=s;
	L->len++;
	return 0;
}

//链表逆置
void LinklistRev(Linklist L)
{
	if(L==NULL||L->next==NULL)
	{
		return;
	}
	Linklist p=L->next;//使用p节点保存第一个节点
	L->next=NULL;
	while(p)
	{
		Linklist t=p;
		p=p->next;
		//把t头插在L头节点的后面
		t->next=L->next;
		L->next=t;
	}
	printf("逆置后的链表为:\n");
	Output(L);
}

//链表排序
void LinklistSort(Linklist L)
{
	Linklist p=L->next;
	L->next=NULL;
	while(p)
	{
		Linklist t=p;
		p=p->next;
		//头节点后面有其他节点
		Linklist q=L;
		while(q->next!=NULL && q->next->data<t->data)
		{
			q=q->next;
		}
		//头节点后面没有节点
		t->next=q->next;
		q->next=t;
	}
	Output(L);
}

//链表释放空间
void Free(Linklist L)
{
	if(L==NULL)
		return ;
	for(int i=0;i<L->len;i++)
	{
		Delete_head(L);
	}
	free(L);
	L=NULL;
}

3)主函数

#include"head1.h"

int main(int argc, const char *argv[])
{
	int n;
	//申请空间
	Linklist L=Create_head();
	//头插
	datatype e1;
	printf("请输入要头插节点的个数:");
	scanf("%d",&n);
	for(int i=0;i<n;i++)
	{
		scanf(" %c",&e1);
		Insert_head(L,e1);
	}
	//单链表遍历
	Output(L);
	//尾插
	datatype e2;
	printf("请输入要尾插节点的个数:");
	scanf(" %d",&n);
	for(int i=0;i<n;i++)
	{
		scanf(" %c",&e2);
		Insert_rear(L,e2);
	}
	Output(L);
	//头删
	Delete_head(L);
	printf("头删之后的链表为:\n");
	Output(L);
	//尾删
	Delete_rear(L);
	printf("头删之后的链表为:\n");
	Output(L);
	//按位置插入
	int pos;
	datatype e;
	printf("请输入插入的位置:");
	scanf("%d",&pos);
	printf("请输入要插入的值");
	scanf(" %c",&e);
	Insert_pos(L,pos,e);
	Output(L);
	//按位置删除
	printf("输入删除的位置:");
	scanf(" %d",&pos);
	Delete_pos(L,pos);
	printf("删除后的链表为:\n");
	Output(L);
	//按位置查找
	printf("输入查找的位置:");
	scanf(" %d",&pos) ;
	Search_pos(L,pos) ;
	//按位置修改
	printf("输入修改的位置:");
	scanf(" %d",&pos) ;
	printf("输入修改的数据元素:");
	scanf(" %c",&e) ;
	Revise_pos(L,pos,e);
	Output(L);
	//按元素查找
	printf("输入查找的元素:");
	scanf(" %c" ,&e);
	Linklist p=Search_data(L,e);
	if(p==NULL)
		printf("查找失败\n");
	else
		printf("%c在链表中\n",p->data);
	//按元素修改
	datatype k;
	printf("输入要修改的元素:") ;
	scanf(" %c" ,&e) ;
	printf("输入修改后的值:");
	scanf(" %c",&k);
	Revise_data(L,e,k);
	//按元素删除
	printf("请输入删除的元素:\n");
	scanf(" %c",&e);
	Delete_data(L,e);
	//在指定元素前插入
	printf("请输入被插入的元素:\n");
	scanf(" %c",&e);
	printf("请输入要插入的元素:\n");
	scanf(" %c",&k);
	Insert_data(L,e,k);
	Output(L);
	//链表逆置
	LinklistRev(L);
	//链表排序
	LinklistSort(L);
	//释放空间
	Free(L);

	
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值