带头结点单链表相关操作

#include<stdio.h>
#include<stdlib.h>  //malloc、free函数的头文件
typedef int ElemType;
typedef struct LNode{  //定义单链表结点类型 
	ElemType data;  //数据域
	struct LNode *next;  //指针域 
}LNode,*LinkList;//使用LNode *强调这是一个结点;使用LinkList强调这是一个单链表 

//1.初始化一个单链表(带头结点)
bool InitList(LinkList &L){
	L = (LNode *)malloc(sizeof(LNode));  //分配一个结点
	if(L==NULL)  //内存不足,分配失败
		return false;
	L->next = NULL; 
	return true;  //头结点之后暂时还没有结点 
}		

//2.采用头插法建立单链表 
LinkList List_HeadInsert(LinkList &L){  //逆向建立单链表 
	LNode *s;  //这里声明一个结点s说明后面肯定要为它分配空间 
	int x; 
	L = (LinkList)malloc(sizeof(L));  //创建头结点
	L->next = NULL;  //初始为空链表
	printf("请输入链表:(当输入9999是结束输入)\n");
	scanf("%d",&x);  //输入结点的值
	while(x!=9999){ //输入9999表示结束 
		s = (LNode *)malloc(sizeof(LNode));  //创建新结点
		s->data = x;
		s->next = L->next; 
		L->next = s;
		scanf("%d",&x);
	} 
	return L;
}

//3.采用尾插法建立单链表
LinkList List_TailInsert(LinkList &L){  //正向建立单链表 
	int x;  //设元素x为整型
	L = (LNode *)malloc(sizeof(LNode));  //创建头结点
	LNode *s,*r = L;  //r为表尾指针
	printf("请输入链表:\n");
	scanf("%d",&x);  //输入结点的值
	while(x!=9999){  //输入9999表示结束 
		s = (LNode *)malloc(sizeof(LNode));  //创建新结点
		s->data = x;
		r->next = s;
		r = s;  //r指向新的表尾结点 
		scanf("%d",&x);  //继续输入
	}
	r->next = NULL;  //尾结点指针置空
	return L; 
} 

//4.在第i个位置插入元素e(带头结点)
bool ListInsert(LinkList &L,int i,int e){
	if(i<1)
		return false;
	LNode *p;  //指针p指向当前扫描的结点
	int j=0;  //当前p指向的是第几个结点
	p = L;   //L指向头结点,头结点是第0个结点(不存数据) 
	while(p!=NULL&&j<i-1){  //循环找到第i-1个结点 
		p = p->next;
		j++; 
	}
	if(p==NULL)  //i值不合法(超出单链表长度) 
		return false;
	LNode *s = (LNode *)malloc(sizeof(LNode));  //创建一个新结点存储元素e
	s->data = e;
	//在p的后面插入s
	s->next = p->next;
	p->next = s;  //将s连到p的后面 
	return true;  //插入成功 
} 

//5.删除第i个结点,并把值带回
bool ListDelete(LinkList &L,int i,int &e){ //&e为了把e的值带回去 
	if(i<1)
		return false;
	LNode *p;  //指针p指向当前扫描的结点
	int j=0;  //当前p指向的是第几个结点
	p = L;   //L指向头结点,头结点是第0个结点(不存数据) 
	while(p!=NULL&&j<i-1){  //循环找到第i-1个结点 
		p = p->next;
		j++; 
	}
	if(p==NULL)  //i值不合法(超出单链表长度) 
		return false;
	if(p->next == NULL)  //第i-1个结点后已无其它结点
		return false;
	LNode *q = p->next;  //用q指向被删除结点
	e= q->data;
	p->next = q->next;  //将*q从链中“断开” 
	free(q);  //释放结点的存储空间
	return true;  //删除成功 
} 

//6.按位查找,返回第i个元素(带头结点)
LNode *GetElem(LinkList L,int i){ //封装 需要找结点位置直接调用该函数 
	if(i<0)
		return NULL;
	LNode *p;  //指针p指向当前扫描的结点
	int j = 0;  //当前p指向的是第几个结点
	p = L;  //L指向头结点,头结点是第0个结点(不存数据)
	while(p!=NULL&&j<i){  //循环找到第i个结点 
		p = p->next;
		j++; 
	}
	return p;  //返回第i个结点,若i大于表长,则返回NULL 
} 

//7.后插操作:在p结点后插入元素e
bool InsertNextNode(LNode *p,int e){
	if(p==NULL)  //i值不合法(超出单链表长度) 
		return false;
	LNode *s = (LNode *)malloc(sizeof(LNode));  //创建一个新结点存储元素e
	s->data = e;
	//在p的后面插入s
	s->next = p->next;
	p->next = s;  //将s连到p的后面 
	return true;  //插入成功 
} 
//8.按值查找表结点
LNode *LocateElem(LinkList L,int e){
	LNode *p = L->next;
	while(p!=NULL&&p->data!=e){  //从第1个结点开始查找data域为e的结点 
		p = p->next;
	return p;  //找到后返回该结点指针,否则返回NULL 
	}
}

//9.对某一结点进行前插操作
bool InsertPriorNode(LinkList L,int i,int e){
	LNode *p = GetElem(L,i-1);  //找到第i-1个结点 
	if(p==NULL)
		return false;
	LNode *s = (LNode *)malloc(sizeof(LNode)); //创建新结点存e的值
	if(s==NULL)
		return false;  //内存分配失败
	s->next = p->next;
	p->next = s;  //将新结点s连到p之后
	s->data = p->data;  //将p中的元素复制到s中 
	p->data = e;  //p中的元素赋值为e
	return true; 
} 

//10.对某一结点进行删除操作
bool DeleteNode(LinkList L,int i){
	LNode *p = GetElem(L,i); //找到第i个结点
	if(p==NULL)
		return false;
	LNode *q = p->next;  //令q指向*p的后继结点
	p->data = p->next->data;//用后继结点的数据域覆盖p(如果p是最后一个结点,这里会出错) 
	p->next = q->next;  //将*q结点从链中“断开”
	free(q);  //释放后继结点的存储空间 
	return true; 
} 

//11.求表长操作
int Length(LinkList L){
	int len = 0;  //统计表长
	LNode *p = L->next;  //指针p指向第一个结点
	while(p!=NULL){
		p = p->next;
		len++;
	} 
	return len;
} 
//12.打印单链表 
void PrintList(LinkList L) {
	LinkList p;	//创建一个指针p
	p = L->next;	//p指向第一个结点 
	printf("链表为:\n");
	while (p != NULL) {	//判断p是否为空
		printf("%d ", p->data);	//依次输入p的数据
		p = p->next;	//指针p每循环一次指向下一个结点元素
	}
	printf("\n");
}

int main(){
	LinkList L;
	InitList(L);
	List_HeadInsert(L);
	PrintList(L); 
	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

m0_54000129

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值