数据结构(二) 单链表的有关操作

PART1 基本概念

1.1 单链表是线性表的链式存储结构,它是指通过一组任意的存储单元来存储线性表的数据元素。

1.2 单链表=结点-结点-结点-结点-结点-结点-结点-结点-结点

结点=数据域(存储单个数据)+指针域(指向下一个结点的指针)

1.3 此数据结构的基本操作为增、删、查、改。

PART2 代码实现

以带头节点的单链表为例

2.1 单链表的结点的类型描述

typedef struct lnode {
	
int data;                //数据域	
struct lnode* next;      //指针域

}lnode,*linklist;

2.2 单链表的建立-头插法/尾插法

2.2.1 头插法建立单链表 (此算法适用于链表的逆置)

linklist List_HeadInsert(linklist& l) {
	lnode* s;
	l = (linklist)malloc(sizeof(lnode));
	l->next = NULL;
	int m;
	scanf("%d", &m);
	while (m != 999) {
		s = (linklist)malloc(sizeof(lnode));
		s->data = m;
		s->next = l->next;
		l->next = s;
		scanf("%d", &m);
	}
	return l;
}

2.2.2 尾插法建立单链表 (此算法正序建立单链表)

linklist List_TailInsert(linklist& l) {
	l = (linklist)malloc(sizeof(lnode));
	l->next = NULL;
	lnode* s, * r = l;
	int m;
	scanf("%d", &m);
	while (m != 999) {
		s = (linklist)malloc(sizeof(lnode));
		s->data = m;
		r->next = s;
		r = s;
		scanf("%d", &m);
	}
	r->next = NULL;
	return l;
}

2.3 按值/位查找

2.3.1 按值查找

lnode* LocateElem(linklist l, int x) {
	lnode* p = l->next;
	while (p != NULL && p->data != x) {
		p = p->next;
	}
	return p;
}

2.3.2 按位查找

lnode* GetElem(linklist l, int i) {
	if (i == 0) return l;
	if (i < 1) return NULL;
	int j = 1;
	lnode* p = l->next;
	while (p != NULL && j < i) {
		p = p->next;
		j++;
	}
	return p;
}

2.4 插入结点

2.4.1 将值为x的结点插入到单链表的第i个位置上

linklist ListInsert(linklist &l, int i,int x) {
	lnode* s,*p;
	s = (lnode*)malloc(sizeof(lnode));
	s->data = x;
	p = GetElem(l, i - 1);
	s->next = p->next;
	p->next = s;
	return l;
}

2.4.2 对某一结点进行前插操作(狸猫换太子)

linklist ListInsert1(linklist& l, int i, int x) {
	lnode* s,*p;
	s = (lnode*)malloc(sizeof(lnode));
	s->data = x;
	p = GetElem(l, i - 1);
	s->next = p->next;
	p->next = s;
	int t =s->data;
	s->data = p->data;
	p->data = t;
	return l;
}

2.5 删除结点

主要思想:先定位到删除的结点,新建结点指向删除结点之后,将后继结点值赋给要删除结点,改变要删除节点的指针,指向新建结点之后,释放新建结点。

linklist ListDelete(linklist& l, int i) {
	lnode* p, * q;
	p = GetElem(l,i);
	q = p->next;
	p->data = p->next->data;
	p->next = q->next;
	free(q);
	return l;
}

2.6 完整版代码

#include <iostream>
using namespace std;

typedef struct lnode {
	int data;
	struct lnode* next;
}lnode,*linklist;

linklist List_HeadInsert(linklist& l) {
	lnode* s;
	l = (linklist)malloc(sizeof(lnode));
	l->next = NULL;
	int m;
	scanf("%d", &m);
	while (m != 999) {
		s = (linklist)malloc(sizeof(lnode));
		s->data = m;
		s->next = l->next;
		l->next = s;
		scanf("%d", &m);
	}
	return l;
}

linklist List_TailInsert(linklist& l) {
	l = (linklist)malloc(sizeof(lnode));
	l->next = NULL;
	lnode* s, * r = l;
	int m;
	scanf("%d", &m);
	while (m != 999) {
		s = (linklist)malloc(sizeof(lnode));
		s->data = m;
		r->next = s;
		r = s;
		scanf("%d", &m);
	}
	r->next = NULL;
	return l;
}
lnode* LocateElem(linklist l, int x) {
	lnode* p = l->next;
	while (p != NULL && p->data != x) {
		p = p->next;
	}
	return p;
}
lnode* GetElem(linklist l, int i) {
	if (i == 0) return l;
	if (i < 1) return NULL;
	int j = 1;
	lnode* p = l->next;
	while (p != NULL && j < i) {
		p = p->next;
		j++;
	}
	return p;
}

linklist ListInsert(linklist &l, int i,int x) {
	lnode* s,*p;
	s = (lnode*)malloc(sizeof(lnode));
	s->data = x;
	p = GetElem(l, i - 1);
	s->next = p->next;
	p->next = s;
	return l;
}

linklist ListInsert1(linklist& l, int i, int x) {
	lnode* s,*p;
	s = (lnode*)malloc(sizeof(lnode));
	s->data = x;
	p = GetElem(l, i - 1);
	s->next = p->next;
	p->next = s;
	int t =s->data;
	s->data = p->data;
	p->data = t;
	return l;
}

linklist ListDelete(linklist& l, int i) {
	lnode* p, * q;
	p = GetElem(l,i);
	q = p->next;
	p->data = p->next->data;
	p->next = q->next;
	free(q);
	return l;
}


void PrintList(linklist l) {
	lnode* p = l->next;
	for (int i = 1; p!=NULL; i++) {
		cout << p->data<<" ";
		p = p->next;
	}
	cout << endl;
}

int main() {
	linklist l1, l2;
	List_HeadInsert(l1);
	PrintList(l1);
	List_TailInsert(l2);
	PrintList(l2);
	ListInsert1(l2, 4, 5);
	PrintList(l2);
	ListDelete(l2, 3);
	PrintList(l2);
	return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Mingyuan Deng

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

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

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

打赏作者

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

抵扣说明:

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

余额充值