使用C语言实现单链表(不带头节点)

目录

1.不带头结点的单链表

2.链表的定义

3.相关操作

(1)初始化操作

(2)销毁操作

(3)获取第i个节点

(4)第i位置插入节点

(5)指定节点的后插操作

(6)按值删除节点和删除第i个节点

(7)按值查询存在性和打印操作

(8)主函数

(9)测试


1.不带头结点的单链表

 

使用C语言实现带头结点的单链表

2.链表的定义

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

typedef int ElemType;

typedef struct LNode {
	ElemType data;
	struct LNode*next;
}LNode,*LinkList;

//清单列表
void MenuLinkList(){
	printf("-------------1.插入操作-------------\n");
	printf("-------------2.定位插入操作---------\n");
	printf("-------------3.按序查找操作---------\n");
	printf("-------------4.按值查找操作---------\n");
	printf("-------------5.定位删除操作---------\n");
	printf("-------------6.按值删除元素---------\n");
	printf("-------------7.删除整个表-----------\n"); 
	printf("-------------8.表的长度-------------\n");
	printf("-------------9.打印操作-------------\n");
	printf("-------------10.结束操作-------------\n");
} 

3.相关操作

(1)初始化操作

//初始化不带头节点
void InitList(LinkList&L){
	L=NULL;
} 

(2)销毁操作

//销毁表的操作
void DestryLinkList(LinkList&L){
	LNode*p=L;
	//首先将第一个节点之后的所有节点删除 
	while(p->next!=NULL){
		LNode*s=p->next;
		p->next=s->next;
		free(s);
	}
	//最后来删除第一个节点
	free(p);
	L=NULL; 
} 

(3)获取第i个节点

//获取单链表的第i个节点 
LNode*GetElem(LinkList L,int i){
	int j=1;
	LNode*p=L;
	if(i<0)return NULL;
	if(i==0)return L;
	while(p!=NULL&&j<i){
		p=p->next;
		j++;
	}
	return p;
} 

(4)第i位置插入节点

//按位序查找第i个节点指针
LNode*FindLNode(LinkList&L,int i){
	if(i<1){
		printf("不符合插入节点位置!\n");
		return NULL;
	}
	int j=1;
	LNode*p=L;
	if(i<0)return NULL;
	if(i==0)return L->next;
	while(p!=NULL&&j<i){
		p=p->next;
		j++;
	}
	return p;
} 
//如果插入的是在第一个节点 ,这需要进行特殊的处理
LNode*InsertFisrtLNode(LinkList&L,ElemType e){
	LNode*s=(LNode*)malloc(sizeof(LNode));
	s->data=e;
	s->next=L;
	L=s;
	printf("插入节点成功!\n");
	return s;
} 
//插入节点到第i个位序中
void ListInsert(LinkList&L,int i,ElemType e){
	//如果i=1,这需要进行特殊的处理 
	if(i==1){
		InsertFisrtLNode(L,e);
		return ;
	} 
	LNode*p=FindLNode(L,i);
	if(p==NULL){
		printf("插入节点的位置不合法!\n");
		return ;
	}
	LNode*s=(LNode*)malloc(sizeof(LNode));
	s->data=e;
	s->next=p->next;
	p->next=s;
	printf("插入节点成功!\n");
} 

(5)指定节点的后插操作

//指定节点的后插操作
LNode* InsertNextNode(LNode*p,ElemType e){
	LNode*s=(LNode*)malloc(sizeof(LNode));
	if(s==NULL){
		printf("内存分配失败!\n");
		return NULL;
	}
	s->data=e;
	s->next=p->next;
	p->next=s;
	printf("插入节点成功!\n");
	return s; 
} 

(6)按值删除节点和删除第i个节点

//表的长度
int LinkListLength(LinkList L){
	LNode*p=L;
	int len=0;
	while(p!=NULL){
		p=p->next;
		len++;
	}
	return len;
} 
//按值删除某个节点
void DeleteElem(LinkList&L,ElemType e){
	if(L==NULL){
		printf("表为空!\n");
		return ;
	}
	int len=LinkListLength(L);
	//用来记录是否为尾节点 
	LNode*p=L;
	LNode*r;
	while(p!=NULL){
		if(p->data==e){
			//处理只有一个节点的时候(特殊) 
			if(len==1){
				free(p);
				L=NULL;
				return ;
			}else{
				//p->next==NULL表示为尾节点,所以要特殊处理 
				if(p->next==NULL){
					LNode*s=p;
					r->next=NULL;
					free(s);
					return ;
				}else{ 
					LNode*s=p->next;
					ElemType temp=p->next->data;
					p->data=temp;
					p->next=s->next;
					free(s);
					return ;
				}	
			}
		}
		r=p;
		p=p->next;
	}
} 
//删除第i个节点
void DeleteLNode(LinkList&L,int i,ElemType&e){
	if(L==NULL){
		printf("表为空!\n");
		return;
	}
	if(i<0||i>LinkListLength(L)){
		printf("删除的位置元素不合法!\n");
		return;
	}
	//特殊情况的处理
	LNode*p=L;
	if(LinkListLength(L)==1){
		free(p);
		L=NULL;
		return ;
	} 
	int j=1;
	while(p!=NULL&&j<i){
		p=p->next;
		j++;
	}
	e=p->data;
	LNode*s=p->next;
	ElemType temp=p->next->data;
	p->data=temp;
	p->next=s->next;
	free(s);
	return ;
} 

(7)按值查询存在性和打印操作

//按值查询节点的存在性
bool FindLNodeExist(LinkList L,ElemType e){
	LNode*p=L;
	while(p!=NULL&&p->data!=e){
		p=p->next;
	}
	if(p==NULL){
		return false;
	}
	return true;
} 

//打印操作
void DisplayLinkList(LinkList L){
	LNode*p=L;
	while(p!=NULL){
		printf("%d\t",p->data);
		p=p->next;
	}
	printf("\n");
} 

(8)主函数

int main(){
	LinkList L;
	InitList(L);
	//对顺序表进行插入操作
	ElemType x;
	int flag=-1;
	int j=1;
	LNode*p=L; 
	//各种操作 
	while(1) {
		int i=0;
		ElemType e=0;
		MenuLinkList();
		printf("请输入操作: ");
		scanf("%d",&flag);
		int len=0;
		LNode*s;
		switch(flag){
			case 1:
				printf("请输入元素(-1_end): ");
				scanf("%d",&x);
				while(x!=-1) {
					//如果插入的是第一个节点,这需要进行特殊的处理 
					if(j==1){
						p=InsertFisrtLNode(L,x);
						j++;
					}else{
						p=InsertNextNode(p,x);
					}
					printf("请输入元素(-1_end): ");
					scanf("%d",&x);
				} 
				break;
			case 2:
				printf("请输入元素插入位置: \n");
				scanf("%d",&i); 
				printf("请输入元素: ");
				scanf("%d",&x);
				ListInsert(L,i,x);
				break;
			case 3:
				printf("请输入查找元素位置: ");
				scanf("%d",&i);
				s=GetElem(L,i);
				if(s!=NULL){
					printf("查找的元素为 = %d\n",s->data);
				}
				break;
			case 4:
				printf("请输入要查找的值: ");
				scanf("%d",&x);
				if(FindLNodeExist(L,x)){
					printf("查找的元素存在!\n");
				}else{
					printf("查找的元素不存在!\n");
				}
				break;
			case 5:
				printf("请输入删除的定位位置: ");
				scanf("%d",&i);
				DeleteLNode(L,i,e);
				printf("删除的元素为 = %d\n",e);
				break;
			case 6:
				printf("请输入要删除的元素: ");
				scanf("%d",&e);
				DeleteElem(L,e);
				printf("删除成功!\n");
				break;
			case 7:
				DestryLinkList(L);
				printf("删除成功!\n");
				break;
			case 8:
				len=LinkListLength(L);
				printf("表的长度 = %d\n",len);
				break;
			case 9:
				DisplayLinkList(L);
				break;
			default:
				DestryLinkList(L);
				printf("结束操作\n");
		}
		if(flag==10){
			break;
		}
	}
	return 0;
}

(9)测试

 

 

 

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值