数据结构(单链表的笔记和方法)

这篇博客详细介绍了如何在C语言中实现带头节点和不带头节点的单链表初始化、插入元素以及删除元素的操作。包括在指定位置插入、删除节点的功能,以及按值和位置查找节点的方法。此外,还提供了头插法和尾插法建立单链表的示例代码。
摘要由CSDN通过智能技术生成
#include<stdio.h>
#include<malloc.h>
typedef int ElemType;
typedef struct LNode{
	ElemType data;
	struct LNode *next;
}LNode,*LinkList;
bool InitList(LinkList&L){//初始化一个空的单链表 ,不带头节点 
	L=NULL;//空表,此时没有任何节点,防止脏数据 
	return true; 
}
bool InitList2(LinkList&L){//带头节点 
	L=(LNode*)malloc(sizeof(LNode));//分配一个头节点
	if (L==NULL)//内存不足,分配失败 
		return false;
	L->next=NULL;//头节点之后暂时没有节点
	return true; 		 	
}
/*单链表的插入和删除*/
//在第i个位置插入元素e(带头节点)
/*好处:
1.第一个数据节点的位置被存放在头节点的指针域里,因此在链表的第一个位置上的操作和在表的其他位置的操作一致
2.无论链表是否为空,其头指针都指向头节点的非空指针
*/ 
bool ListInsert(LinkList&L,int i,ElemType 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));
	s->data=e;
	s->next=p->next;
	p->next=s;
	return true;//插入成功 
} 
//不带头节点 
bool ListInsert2(LinkList&L,int i,ElemType e){
	if(i<1)
		return false;
	if(i==1){
		//插入第一个节点的操作不同
		LNode *s=(LNode*)malloc(sizeof(LNode));
		s->data=e;
		s->next=L;
		L=s;//头指针指向新的节点 
		return true; 
	}
	LNode*p;//p指向当前扫描到的节点
	int j=1;//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));
	s->data=e;
	s->next=p->next;
	p->next=s;
	return true;//插入成功 
} 
/*在p结点之后插入元素e*/
bool InsertNextNode(LNode*p,ElemType e){
	if (p==NULL)
		return false;
	LNode*s=(LNode*)malloc(sizeof(LNode));
	if(s==NULL)//内存分配失败
		return false;
	s->data=e;
	s->next=p->next;
	p->next=s;
	return true; 
} 
/*在p节点之前插入元素e*让e成为p的后继节点是可以操作的,然后把两个表中的数据域互换*/
bool InsertPriorNode(LNode*p,ElemType e) {
	if(p==NULL)
		return false;
	LNode *s=(LNode*)malloc(sizeof(LNode));
	if (s==NULL)
		return false;
	s->next=p->next;
	p->next=s;
	s->data=p->data;//把数据做一个交换 
	p->data=e; 
}
/*带头节点的删除某一位置i 的元素*/
bool ListDelete(LinkList&L,int i,ElemType&e){
	if(i<1)
		return false;
	LNode*p;
	int j=0;
	p=L;
	while (p!=NULL && j<i-1){//和插入一样的操作,为了找到第i-1个节点 
		p=p->next;
		j++;
	}
	if(p==NULL)//i值不合法
		return false;
	if(p->next==NULL)//要删除的节点是空
		return false;
	LNode*q=p->next;/*让一个指针q指向要被删除的节点*/// 
	e=q->data;//返回元素值
	p->next=q->next;//让*q元素从列表中断开
	free(q);
	return true; 
} 
/*删除指定节点p*/
bool DeleteNode(LNode*p){
	/*类似于后插,p不能是最后一个元素*/
	/*单链表不能逆向检索--双链表*/ 
	if(p==NULL)
		return false;
	LNode*q=p->next;//q指向p所指向元素的后继 
	p->data=p->next->data; //把p的数据域换成后继的数据域,还差个next没换,next指向*p的next指向即可,然后把q所指向的地址free掉
	p->next=q->next;
	free(q);
	return true; 
} 
/*按位查找,返回第i个元素,带头节点,设其为0*/ 
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++; 		
	} 
} 
/*按值查找,找到数值为e 的节点*/
LNode *LocateElem(LinkList L,ElemType e){
	LNode *p=L->next;
	//从第一个节点开始查找,如果是struct类型,我们就需要额外写一个函数依次比较里面的元素 
	while(p!=NULL&&p->data!=e)
		p=p->next;
	return p; 
} 
/*求表长*/
int length(LinkList L){
	int len=0;
	LNode *p=L;
	while(p->next!=NULL){
		p=p->next;
		len++;
	}
	return len;
} 
/*尾插法建立单链表*/ 
LinkList List_TailInsert(LinkList&L){//正向建立单链表 
	int x;
	L=(LinkList)malloc(sizeof(LNode));
	LNode*s,*r=L;//r为表尾指针 
	scanf("%d",&x);
	while(x!=9999){
		s=(LNode*)malloc(sizeof(LNode));//在头节点之后创建一个新的节点 
		s->data=x;//数据域 
		r->next=s;//节点之间连接 
		r=s;//r指向尾节点 
		scanf("%d",&x);
	} 
	r->next=NULL;
	return L; 
} 
/*头插法建立单链表--调用后插操作--链表的逆置(把新的节点插入到表头后面)*/ 
LinkList List_HeadInsert(LinkList&L){
	//逆向建立单链表,按照输入元素的逆序进行输出构造链表 
	LNode *s;
	L=(LinkList)malloc(sizeof(LNode));
	L->next=NULL;//重要,防止NULL指向未知的地址,受脏数据的影响 
	scanf("%d",&x);
	while(x!=9999)
	{
		s=(LNode*)malloc(sizeof(LNode));//创建新的节点,实际上就是后插操作 
		s->data=x;
		s->next=L->next;
		L->next=s; 
	 } 
} 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值