C/C++数据结构函数定义(2)线性表-单链表

1.初始设置定义

typedef int ElemType; // ElemType代表元素数据类型,可自定义类型 

2.单链表结点设置定义

typedef struct LNode{ // 单链表的结点定义 
	ElemType data; // 链表的数据域 
	struct LNode *next; // 链表的指针域,指向后继结点 
}LNode, *LinkList;

3.初始化创建带头结点的空链表

bool InitList_L(LinkList &L){ // 构造一个空的单链表L 
	L = new LNode; // 生成新的头结点,用头指针L指向头结点 
	if(!L)return false; // 生成结点失败 
	L->next = NULL; // 头结点的指针置空 
	return true;
} 

4.利用头插法创建单链表

void CreateList_H(LinkList &L){ // 利用头插法创建单链表 
	int n; // 输入n个元素的值,连接在带头结点的单链表上 
	LinkList s; 
	L = new LNode; // 建立一个带头结点L的空链表 
	L->next = NULL; // 当前头结点L的后继为空 
	printf("请输入元素个数n:");
	scanf("%d",&n);
	printf("请依次输入n个元素:\n");
	while(n--){
		s = new LNode; // 生成新的结点s 
		scanf("%d",&s->data); // 将输入数据赋给新结点s的数据域 
		s->next = L->next; // 将新结点s插入头结点L之后 
		L->next = s; // 令头结点指向当前新插入的结点 
	}
}

5.利用尾插法创建单链表

void CreateList_R(LinkList &L){ // 利用尾插法创建单链表 
	int n; // 输入n个元素的值,连接在带头结点的单链表上 
	LinkList s,r; 
	L = new LNode; // 建立一个带头结点L的空链表 
	L->next = NULL; // 当前头结点L的后继为空 
	r = L; // 当前单链表仅有头结点L,所以头结点L也即当前尾结点r 
	printf("请输入元素个数n:");
	scanf("%d",&n);
	printf("请依次输入n个元素:\n");
	while(n--){
		s = new LNode; // 生成新的结点s 
		scanf("%d",&s->data); // 将输入数据赋给新结点s的数据域 
		s->next = NULL; // 新结点s将作为新的尾结点所以其后继为空 
		r->next = s; // 令r指向新结点s使新结点s插入原尾结点r之后
		r = s; // 当前尾结点为s,则更新r为最新尾结点 
	}
}

6.在单链表中查找第i个元素的值

bool GetElem_L(LinkList L, int i, int &e){ // 在带头结点的单链表L中查找第i个元素
	// 用e记录L中第i个元素的值
	int j = 1; // j为计数器 
	LinkList p;
	p = L->next; // p指向第一个数据结点,以此为起点 
	while(j<i && p){ // 顺着链表向后扫描,直至p指向第i个元素或p为空 
		p = p->next; // 指向下一个结点 
		j++; // 计数+1 
	} 
	if(!p || j>i)return false; // 当i值超限则查找失败 
	e = p->data; // 取第i个结点的数据域 
	return true;
}

7.在单链表中查找元素e是否存在

bool LocateElem_L(LinkList L, int e){ // 在带头结点的单链表中查找元素e是否存在 
	LinkList p;
	p = L->next; // p指向第一个数据结点,以此为起点 
	while(p && p->data!=e) // 顺着链表向后扫描,直至p指向元素e或p为空
		p = p->next;
	if(!p)return false;  // 当p值为空则查找失败 
	return true;
}

8.在单链表的第i个位置插入元素e

bool ListInsert_L(LinkList &L, int i, int e){ // 在带头结点的单链表中第i个位置插入元素e 
	int j = 0;
	LinkList p,s;
	p = L; // p指向头结点,以此为起点
	while(p && j<i-1){ // 顺着链表向后扫描,直至p指向第i-1个位置或p为空
		p = p->next;
		j++;
	}
	if(!p || j>i-1)return false; // 当i超限时插入失败 
	s = new LNode; // 生成新结点s 
	s->data = e; // 将e放入新结点s的数据域 
	s->next = p->next; // 将新结点的指针域指向第i个结点 
	p->next = s; // 将结点p的指针域指向结点s 
	return true;
}

9.在单链表中删除第i个位置元素

bool ListDelete_L(LinkList &L, int i){ // 在带头结点的单链表中删除第i个位置元素 
	LinkList p,q;
	int j = 0;
	p = L; // p指向头结点,以此为起点
	while((p->next) && (j<i-1)){ // 查找被删除结点的前驱结点 
		p = p->next;
		j++;
	} 
	if(!(p->next) || (j>i-1))return false; // 当被删除结点为空或i超限时查找失败
	q = p->next; // 临时保存被删除结点的地址,使q作为当前被删除结点 
	p->next = q->next; // 将q结点的后继地址赋给p结点的指针域 
	delete q; // 释放q的内存空间以实现删除 
	return true;
}

10.合并有序单链表La和Lb

void MergeLinkList(LinkList La, LinkList Lb, LinkList &Lc){ // 合并有序单链表La和Lb生成Lc 
	LinkList p,q,r;
	p = La->next; // p指向La的第一个元素结点 
	q = Lb->next; // q指向Lb的第一个元素结点
	Lc = La; // Lc指向La的头结点 
	r = Lc; // r指向新链表Lc的尾结点 
	while(p && q){
		if(p->data <= q->data){ // 串起p指向的结点 
			r->next = p;
			r = p;
			p = p->next;
		}else{ // 串起q指向的结点 
			r->next = q;
			r = q;
			q = q->next;
		}
	}
	r->next = p ? p : q; // 相当于if(p)r->next = p;else r->next = q; 
	delete Lb;
}

11.将单链表元素顺序倒置

void ReverseLinkList(LinkList &L){ // 将单链表元素顺序倒置 
	LinkList p,q;
	p = L->next; // p指向L的第一个元素 
	L->next = NULL; // 头结点后继置空 
	while(p){
		q = p->next; // q指向p的下一结点,记录断点 
		p->next = L->next; // 头插法 
		L->next = p;
		p = q; // 指针后移 
	}
}

12.查找链表中间结点(单双链表均适用)

LinkList FindMiddle(LinkList L){ // 查找链表中间位置结点 
	LinkList p,q;
	p = L; // p为快指针 
	q = L; // q为慢指针 
	while(p && p->next){
		p = p->next->next; // 快指针p一次经过两个结点 
		q = q->next; // 慢指针q一次经过一个结点 
	}
	return q; // 此时q的位置即为单链表中间结点位置 
}

13.查找链表倒数第k位结点(单双链表均适用)

LinkList FindK(LinkList L, int k){ // 查找链表倒数第k位结点 
	LinkList p,q;
	p = L->next; // p为快指针 
	q = L->next; // q为慢指针 
	while(p->next){
		if(--k <= 0)q = q->next; // k减至0时,慢指针q开始走 
		p = p->next; // 快指针p先走k-1步 
	}
	if(k>0)return NULL; // 若倒数第k位不存在则返回空 
	else return q; // 若存在倒数第k位则将其结点返回 
} 

14.单链表元素去重

void DeleteRep(LinkList &L){ // 单链表去重 
	LinkList p,q;
	int x;
	bool flag[n+1] = {}; // 标记出现过的元素,n为单链表中元素最大值 
	p = L; // 指向头结点 
	while(p->next){
		x = abs(p->next->data);
		if(flag[x]){ // 若该元素出现过 
			q = p->next; // q指向p的下一结点 
			p->next = q->next; // 删除重复元素结点 
			delete q; // 释放重复元素结点空间 
		}else{ // 若该元素未出现过 
			flag[x] = 1; // 在标记数组的元素位做标记 
			p = p->next; // 指针后移 
		}
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

尘枫--odin

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

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

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

打赏作者

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

抵扣说明:

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

余额充值