考研数据结构:(二)单链表(不带头节点)的基本操作(只有干货)

/*
	Author: panxiaolan
	Time: 2021-10-09

	单链表的基本操作(不带头节点):
	(1).单链表的定义
	(2).单链表的初始化
	(3).单链表建立
		a.头插法建立单链表
		b.尾插法建立单链表
	(4).单链表查找
		a.按位查找
		b.按值查找
	(5).单链表的长度
	(6).单链表插入 
		a.后插
		b.前插
		c.在某个位置插入 
	(7).单链表删除 
		a.删除指定位序上的元素
		b.删除某个节点 
	(8).单链表的输出 

*/

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

// 单链表的定义
typedef struct LNode {
	int data;
	LNode *next;
} LNode,*ListLink;

// 单链表的初始化
void InitListLink(ListLink &L) {
	L = NULL;
	return ;
}

// 头插法建立单链表
ListLink Head_Create_ListLink(ListLink &L) {
	InitListLink(L);
	LNode *s;
	int x;
	while(scanf("%d",&x) != EOF) {
		if(x == -1) break;
		s = (LNode *)malloc(sizeof(LNode));
		s->data = x;
		s->next = L;	// 插入到头部
		L = s;			// 更新头部,这两步顺序不能乱
	}

	return L;
}

// 尾插法建立单链表
ListLink Tail_Create_ListLink(ListLink &L) {
	InitListLink(L);
	bool is_head = true;
	int x;
	LNode *s,*r = L;
	while(scanf("%d",&x) != EOF) {
		if(x == -1) break;
		s = (LNode *)malloc(sizeof(LNode));

		if(is_head) {
			is_head = false;
			s->data = x;
			s->next = NULL;
			L = s;
			r = s;
		}
		// s 是新插入的节点
		s->data = x;
		// 此句可以省略,便于理解此处不再省略
		s->next = NULL;
		// 将新节点插入到尾队列中
		r->next = s;
		// r 重新指向尾部
		r = s;
	}
	r->next = NULL;
	return L;
}

// 按位查找,返回第 i 个节点(不带头节点)
LNode* getElem(ListLink &L,int i) {
	if(i < 1) return NULL;
	LNode *p = L;
	int j = 1;
	while(p && j < i) {
		p = p->next;
		j ++;
	}
	return p;
}

// 按值查找,找到数据域是 e 的节点
LNode* locateElem(ListLink &L,int e) {
	LNode *p;
	p = L;
	while(p && p->data != e) {
		p = p->next;
	}
	return p;
}


// 获取单链表的长度
int length(ListLink &L) {
	int len = 0;
	LNode *p = L;
	while(p) {
		len ++;
		p = p->next;
	}
	return len;
}

// 后插操作: 在节点 P 之后插入元素 e
bool InsertNextNode(LNode *p,int e) {
	if(!p) return false;
	LNode *s;
	s = (LNode *)malloc(sizeof(LNode));
	if(!s) return false;
	s->data = e;
	s->next = p->next;
	p->next = s;
	return true;
}

// 插入操作,在第 i 个位置插入元素 e
bool InsertNode(ListLink &L,int i,int e) {
	LNode *p;
	p = getElem(L,i - 1);
	LNode *s;
	s = (LNode *)malloc(sizeof(LNode));
	s->data = e;
	// 后插操作
	s->next = p->next;
	p->next = s;
	return true;
}


// 前插操作:在 p 节点前插入元素 e
bool InsertBeforeNode(LNode *p,int e) {
	if(!p) return false;
	LNode *s;
	s = (LNode *)malloc(sizeof(LNode));
	if(!s) return false;
	// s 现在的位置就是之前 p 的位置
	s->next = p->next;
	p->next = s;
	s->data = p->data;
	p->data = e;

	return true;
}


// 前插操作: 在 P 节点前插入节点 s
bool InsertNodeS(LNode *p,LNode *s) {
	if(!p || !s) return false;
	s->next = p->next;
	p->next = s;
	// 交换两个节点的数据域
	int temp = s->data;
	s->data = p->data;
	p->data = temp;
	return true;
}


// 删除操作: 删除 位序 i 的节点, e 是 i 节点的值
bool DeletePositionNode(ListLink &L,int i,int &e) {
	if(i < 1) return false;
	if(i > 1) {
		LNode *p;
		p = getElem(L,i - 1);
		LNode *q = p->next;
		e = q->data;
		p->next = q->next;
		free(q);
	} else {
		// i = 1 是头节点
		if(L->next == NULL) {
			e = L->data;
			L = NULL;
		} else {
			e = L->data;
			L = L->next;
		}
	}
	return true;
}

// 删除操作 : 删除某个节点
bool DeleteNode(LNode *p) {
	if(p->next == NULL) return false;
	LNode *q;
	q = p->next;
	p->data =  q->data;
	p->next = q->next;
	return true;
}


// 单链表的输出
void print(ListLink &L) {
	LNode *s = L;
	while(s != NULL) {
		printf("%d ",s->data);
		s = s->next;
	}
	printf("\n");
	return ;
}


int main() {

	ListLink L;
	// 头插法建立单链表
	printf("-------------头插法建立单链表--------------\n");
//	Head_Create_ListLink(L);
	// 尾插法建立单链表
	printf("-------------尾插法建立单链表--------------\n");
	Tail_Create_ListLink(L);
	printf("-------------输出节点--------------\n");
	// 输出节点
	print(L);
	printf("-------------按位序查找元素--------------\n");
	LNode *p = getElem(L,2);
	printf("%d \n",p->data);

	printf("-------------按值查找元素--------------\n");
	LNode *q = locateElem(L,3);
	printf("%d \n",q->data);

	printf("-------------单链表的长度--------------\n");
	int len = length(L);
	printf("%d \n",len);

	printf("-------------后插操作: 在节点 P 之后插入元素 e--------------\n");

	printf("在第 3 个元素后插入元素 e \n");
	LNode *after;
	after = getElem(L,3);
	InsertNextNode(after,100);
	printf("插入后的单链表\n");
	print(L);

	printf("-------------插入操作,在第 i 个位置插入元素 e--------------\n");
	InsertNode(L,2,1001);
	printf("在第 2 个位置插入1001操作完成后的单链表:\n");
	print(L);

	printf("-------------前插操作:在 p 节点前插入元素 e--------------\n");
	LNode *before;
	before = getElem(L,4);
	InsertBeforeNode(before,99999);
	printf("在第 4 个位置前插操作完成后的单链表:\n");
	print(L);


	printf("-------------前插操作: 在 P 节点前插入节点 s--------------\n");
	LNode *first;
	first = (LNode *)malloc(sizeof(LNode));
	first->data = 12345678;
	InsertNodeS(before,first);
	printf("插入 first 节点后的序列:\n");
	print(L);

	printf("------------- 删除操作: 删除 位序 i 的节点, e 是 i 节点的值--------------\n");
	int e;
	printf("未删除元素的单链表:\n");
	print(L);
	DeletePositionNode(L,3,e);
	printf("删除后的单链表是:\n");
	print(L);
	printf("删除元素的值是: %d \n",e);

	printf("------------- 删除操作 : 删除某个节点--------------\n");
	LNode *deleteDot;
	deleteDot = getElem(L,1);
	printf("未删除元素的单链表:\n");
	print(L);
	DeleteNode(deleteDot);
	printf("删除后的单链表是:\n");
	print(L);
	return 0;
}

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

潘小蓝

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

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

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

打赏作者

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

抵扣说明:

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

余额充值