双链表及其常用操作(C++)

目录

1.节点定义

2.初始化链表

3.建立双链表

头插法

尾插法

4.遍历输出

5.求链表长度

6.查找

按位查找

返回第i个节点的指针

按值查找

7.插入

8.删除

9.连接链表

10.链表排序

11.判空

完整代码


1.节点定义

typedef struct LNode {
	int data;
	struct LNode* next, * prior;		//后继指针,前驱指针
}LNode, * LinkList;

2.初始化链表

申请一个空的头结点

//初始化
void InitList(LinkList& L) {
	L = (LinkList)malloc(sizeof(LNode));
	L->next = NULL;
	L->prior = NULL;
	L->data = 0;						//保存链表长度(不管也可以)
}

3.建立双链表

头插法

//头插法
LinkList HeadInsert(LinkList& L) {
	InitList(L);
	int x;
	cin >> x;
	while (x != 9999) {                 //输入9999代表输入结束
		L->data++;						//统计链表长度
		LinkList s = (LinkList)malloc(sizeof(LNode));
		s->data = x;
		//如果链表为空,只用实现向L后插入
		if (L->next == NULL) {
			s->next = NULL;
			s->prior = L;
			L->next = s;
		}
		else {
			//前三步顺序可变,最后一步不能动,否则会导致插入失败
			s->next = L->next;			//s指向下一个结点r        插入前(L  r)      插入后(L s r)
			s->prior = L;				//s的前驱指针指向头结点L
			L->next->prior = s;			//下一个结点r的前驱指针指向s
			L->next = s;				//头结点L的后继指针指向s
		}
		cin >> x;
	}
	return L;
}

尾插法

//尾插法
LinkList TailInsert(LinkList& L) {
	InitList(L);
	LinkList s, r = L;					//r永远指向最后一个结点
	int x;
	cin >> x;
	while (x != 9999) {
		L->data++;
		s = (LinkList)malloc(sizeof(LNode));
		s->data = x;
		s->next = NULL;
		s->prior = r;
		r->next = s;
		r = s;							//最后一步执行,让r指向最后一个结点
		cin >> x;
	}
	return L;
}

4.遍历输出

//遍历打印
void PrintList(LinkList L) {
	LinkList p = L->next;
	while (p) {
		cout << p->data << " ";
		p = p->next;
	}
	cout << "共" << L->data << "个结点" << endl;
}

5.求链表长度

//求链表长度(用不到前驱指针,和单链表写法相同)
//如果定义L->data为链表长度,也可以直接输出L->data
int Length(LinkList L) {
	int len = 0;
	LinkList p = L->next;
	while (p) {
		len++;
		p = p->next;
	}
	return len;
}

6.查找

按位查找

//按位查找
void SearchI(LinkList L, int i) {
	if (i > L->data) {                    //if(i>Length(L)){}
		cout << "没有第" << i << "位" << endl;
		return;
	}
	int k = 0;
	LinkList p = L->next;
	while (p) {
		k++;
		if (k == i) {
			cout << "第" << i << "位为" << p->data << endl;
			return;
		}
		p = p->next;
	}
}

返回第i个节点的指针

LinkList SearchTool(LinkList L, int i) {
	LinkList p = L;
	int k = 0;
	while (k < i) {
		p = p->next;
		k++;
	}
	return p;
}

按值查找

//按值查找
void SearchData(LinkList L, int data) {
	LinkList p = L->next;
	int i = 1;
	while (p) {
		if (p->data == data) {
			cout << data << "是第" << i << "位" << endl;
			return;
		}
		p = p->next;
		i++;
	}
	if (p == NULL)
		cout << "查找失败" << endl;
	return;
}

7.插入

//插入(第i个结点之前)
void InsertIP(LinkList L, int i,int data) {
	LinkList p = SearchTool(L,i-1);					//p为第i-1个结点,p->next为第i个结点
	LinkList s = (LinkList)malloc(sizeof(LNode));
	L->data++;
	if (p->next == NULL) {
		s->data = data;
		s->next = NULL;
		s->prior = p;
		p->next = s;
	}
	else {
		s->data = data;
		s->next = p->next;
		s->prior = p;
		p->next->prior = s;
		p->next = s;
	}
	PrintList(L);
}
//(第i个结点之后)
void InsertIN(LinkList L, int i, int data) {
	LinkList p = SearchTool(L, i);
	LinkList s = (LinkList)malloc(sizeof(LNode));
	s->data = data;
	s->next = p->next;
	s->prior = p;
	p->next = s;
	L->data++;
	PrintList(L);
}

8.删除

//删除第i个结点
void DeleteI(LinkList L, int i) {
	LinkList p = SearchTool(L, i);
	//(L,p->prior,p,p->next)
	if (p->next == NULL) {				//如果第i个结点是最后一个结点
		p->prior->next = NULL;
	}
	else {
		p->prior->next = p->next;
		p->next->prior = p->prior;
	}
	L->data--;
	PrintList(L);
}

9.连接链表

//连接两个链表,N接在M后面
LinkList AddList(LinkList M, LinkList N) {
	LinkList p = M->next;
	LinkList q = N->next;
	while (p->next != NULL)
		p = p->next;
	p->next = q;
	q->prior = p;
	M->data += N->data;
	return M;
}

10.链表排序

//链表排序
void SortList(LinkList L) {
	LinkList tail, p, q;
	tail = NULL;
	while (L->next->next != tail) {
		p = L;
		q = L->next;
		while (q->next != tail) {
			if (q->data > q->next->data) {
				p->next = q->next;
				q->next = p->next->next;
				p->next->next = q;
				q = p->next;
			}
			q = q->next;
			p = p->next;
		}
		tail = q;
	}
}

11.判空

//判空
bool EmptyList(LinkList L) {
	if (L->next == NULL)
		return true;
	else
		return false;
}

完整代码

#include<iostream>
using namespace std;

typedef struct LNode {
	int data;
	struct LNode* next, * prior;		//后继指针,前驱指针
}LNode, * LinkList;


//初始化
void InitList(LinkList& L) {
	L = (LinkList)malloc(sizeof(LNode));
	L->next = NULL;
	L->prior = NULL;
	L->data = 0;						//保存链表长度(不管也可以)
}


//头插法
LinkList HeadInsert(LinkList& L) {
	InitList(L);
	int x;
	cin >> x;
	while (x != 9999) {
		L->data++;						//统计链表长度
		LinkList s = (LinkList)malloc(sizeof(LNode));
		s->data = x;
		//如果链表为空,只用实现向L后插入
		if (L->next == NULL) {
			s->next = NULL;
			s->prior = L;
			L->next = s;
		}
		else {
			//前三步顺序可变,最后一步不能动,否则会导致插入失败
			s->next = L->next;			//s指向下一个结点r        插入前(L  r)      插入后(L s r)
			s->prior = L;				//s的前驱指针指向头结点L
			L->next->prior = s;			//下一个结点r的前驱指针指向s
			L->next = s;				//头结点L的后继指针指向s
		}
		cin >> x;
	}
	return L;
}


//尾插法
LinkList TailInsert(LinkList& L) {
	InitList(L);
	LinkList s, r = L;					//r永远指向最后一个结点
	int x;
	cin >> x;
	while (x != 9999) {
		L->data++;
		s = (LinkList)malloc(sizeof(LNode));
		s->data = x;
		s->next = NULL;
		s->prior = r;
		r->next = s;
		r = s;							//最后一步执行,让r指向最后一个结点
		cin >> x;
	}
	return L;
}


//遍历打印
void PrintList(LinkList L) {
	LinkList p = L->next;
	while (p) {
		cout << p->data << " ";
		p = p->next;
	}
	cout << "共" << L->data << "个结点" << endl;
}


//求链表长度(用不到前驱指针,和单链表写法相同)
//也可以直接输出L->data
int Length(LinkList L) {
	int len = 0;
	LinkList p = L->next;
	while (p) {
		len++;
		p = p->next;
	}
	return len;
}


//查找(与单链表写法相同)
//按位查找
void SearchI(LinkList L, int i) {
	if (i > L->data) {
		cout << "没有第" << i << "位" << endl;
		return;
	}
	int k = 0;
	LinkList p = L->next;
	while (p) {
		k++;
		if (k == i) {
			cout << "第" << i << "位为" << p->data << endl;
			return;
		}
		p = p->next;
	}
}


//工具性函数,返回第i个结点的指针
LinkList SearchTool(LinkList L, int i) {
	LinkList p = L;
	int k = 0;
	while (k < i) {
		p = p->next;
		k++;
	}
	return p;
}


//按值查找
void SearchData(LinkList L, int data) {
	LinkList p = L->next;
	int i = 1;
	while (p) {
		if (p->data == data) {
			cout << data << "是第" << i << "位" << endl;
			return;
		}
		p = p->next;
		i++;
	}
	if (p == NULL)
		cout << "查找失败" << endl;
	return;
}


//插入(第i个结点之前)
void InsertIP(LinkList L, int i,int data) {
	LinkList p = SearchTool(L,i-1);					//p为第i-1个结点,p->next为第i个结点
	LinkList s = (LinkList)malloc(sizeof(LNode));
	L->data++;
	if (p->next == NULL) {
		s->data = data;
		s->next = NULL;
		s->prior = p;
		p->next = s;
	}
	else {
		s->data = data;
		s->next = p->next;
		s->prior = p;
		p->next->prior = s;
		p->next = s;
	}
	PrintList(L);
}
//(第i个结点之后)
void InsertIN(LinkList L, int i, int data) {
	LinkList p = SearchTool(L, i);
	LinkList s = (LinkList)malloc(sizeof(LNode));
	s->data = data;
	s->next = p->next;
	s->prior = p;
	p->next = s;
	L->data++;
	PrintList(L);
}


//删除第i个结点
void DeleteI(LinkList L, int i) {
	LinkList p = SearchTool(L, i);
	//(L,p->prior,p,p->next)
	if (p->next == NULL) {				//如果第i个结点是最后一个结点
		p->prior->next = NULL;
	}
	else {
		p->prior->next = p->next;
		p->next->prior = p->prior;
	}
	L->data--;
	PrintList(L);
}


//连接两个链表,N接在M后面
LinkList AddList(LinkList M, LinkList N) {
	LinkList p = M->next;
	LinkList q = N->next;
	while (p->next != NULL)
		p = p->next;
	p->next = q;
	q->prior = p;
	M->data += N->data;
	return M;
}


//链表排序
void SortList(LinkList L) {
	LinkList tail, p, q;
	tail = NULL;
	while (L->next->next != tail) {
		p = L;
		q = L->next;
		while (q->next != tail) {
			if (q->data > q->next->data) {
				p->next = q->next;
				q->next = p->next->next;
				p->next->next = q;
				q = p->next;
			}
			q = q->next;
			p = p->next;
		}
		tail = q;
	}
}

//判空
bool EmptyList(LinkList L) {
	if (L->next == NULL)
		return true;
	else
		return false;
}


int main() {
	int i, data, ii, insertdata, iii;
	LinkList L = TailInsert(L);
	PrintList(L);
//	cout << "请输入要查找的位置和数据:";
//	cin >> i >> data;
//	SearchI(L, i);
//	SearchData(L, data);
//	cout << "输入在哪一位插入的值:";
	cout << "输入在哪一位后方插入一个结点:";
	cin >> ii >> insertdata;
	InsertIN(L, ii, insertdata);
//	InsertIP(L, ii, insertdata);
//	cout << "要删除第几位:";
//	cin >> iii;
//	DeleteI(L, iii);
	if (EmptyList(L))
		cout << "链表为空";
	else
		cout << "链表不为空";
	//LinkList M = TailInsert(M);
	//LinkList N = TailInsert(N);
	//M = AddList(M, N);
	//PrintList(M);
	return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值