(4)链表(单链表)

链表:单链表

以链式结构存储结构的线性表称为线性链表。
元素本身的信息和其后期信息组成数据元素的存储映像,称为结点;

线性链表有三种:
1)单链表
2)双链表
3)循环链表。
对链表的任何操作都必须从第一个结点开始,第一个结点的地址存放在一个指针变量中,这个指针变量指向第一个结点,
也就是链表最前面的结点,因此这个指针变量常称为头指针。

我们在整个线性链表的第一个结点之前加入一个结点称为头结点。

链表优缺点:
缺:失去了顺序存储结构的随机存储特点,在查找等算法中要比顺序存储结构慢。
优:插入或删除要比顺序表方便得多。

单链表的表示:
单链表是最简单的一种链式结构。表中每个元素结点包括两部分:数据域和后继节点的地址域。
地址域:存放数据元素信息的域。
指针域:存放后期地址的域。
因为每个结点中只有一个指向后继的指针,所以就称为单链表。

单链表的实现:头插法和尾插法两种。同时也分带结点和不带结点!

头插法:


尾插法:


单链表的基本操作:
1)Length(L) 返回表L的长度,即表中元素个数
2)Prior(L,i) 取位置i的前驱元素
3)Next(L,i) 取位置i的后继元素
4)Locate(L,x) 这是一个函数,函数值为元素x在L中的位置
5)Insert(L,i,x)在表L的位置i处插入元素x,将原占据位置i的元素及后面的元素都向后推一个位置
6)Delete(L,p) 从表L中删除位置p处的元素
7)Get(L,i) 这是一个函数,函数值为L中位置i处的元素(1≤i≤n)
8)Empty(L) 如果表L为空表(长度为0)则返回true,否则返回false
9)Clear(L)清除所有元素
10)Traverse(L)遍历输出所有元素
11)Update(L,i,x)修改元素
12)退出
13)清空命令行!
14)CreateT() 头插法
15)CreateW1() 尾插法(带头结点)

16)CreateW2()尾插法(不带头结点)


代码:

#include<iostream>
#include<cstdlib>
#include<malloc.h>
using namespace std;
typedef int dataType;
typedef struct Node{
	dataType data=-1;
	struct Node *next;
}LNode,*LinkedList;
//创建链表  头插法
LinkedList linkedListCreateT() {
	int i = 1;
	LinkedList l = (LNode*)malloc(sizeof(LNode));
	if (l == NULL) {
		cout << "创建失败没有足够空间!" << endl;
		return l;
	}
	l->next = NULL;
	while (i != 21) {
		LinkedList p = (LNode*)malloc(sizeof(LNode));
		p->data = i;
		++i;
		p->next = l->next;
		l->next = p;
	}
	cout << "头插法单链表创建成功!" << endl;
	return l;
}
//创建链表  尾插法 带头结点
LinkedList linkedListCreateW1() {
	int i = 1;
	LinkedList r;
	LinkedList l = (LNode*)malloc(sizeof(LNode));
	if (l == NULL) {
		cout << "创建失败没有足够空间!" << endl;
		return l;
	} 
	l->next = NULL;
	r = l;
	while (i != 21) {
		LinkedList p = (LNode*)malloc(sizeof(LNode));
		p->data = i;
		++i;
		p->next = r->next;
		r->next = p;
		r = p;
	}
	cout << "尾插法带头结点单链表创建成功!" << endl;
	return l;
}
//创建链表  尾插法 不带头结点
LinkedList linkedListCreateW2() {
	int i = 1;
	LinkedList r;
	LinkedList l = (LNode*)malloc(sizeof(LNode));
	if (l == NULL) {
		cout << "创建失败没有足够空间!" << endl;
		return l;
	}
	l->next = NULL;
	r = l;
	while (i != 21) {
		LinkedList p = (LNode*)malloc(sizeof(LNode));
		p->data = i;
		++i;
		if (l == NULL) l = p;
		else r->next = p;
		r = p;
	}
	if (r != NULL) r->next = NULL;
	cout << "尾插法不带头结点单链表创建成功!" << endl;
	return l;
}
//表中元素个数
int  linkedListLength(LinkedList l) {
	int i=0;
	LinkedList p;
	if (l->data > 0) {
		p = l;
		while (p!= NULL) {
			++i;
			p = p->next;
		}
	}
	else {
		p = l->next;
		while (p!= NULL) {
			++i;
			p = p->next;
		}
	}
	return i;
}
//函数值为L中位置i处的元素
void linkedListGet(LinkedList l,int i) {
	if (i<1 || i> linkedListLength(l)) cout << "超出链表表长度!请重新输入!" << endl;
	else { 
		int j = 0;
		LinkedList p;
		if (l->data != NULL) {
			p = l;
			while (p->next != NULL && j!= i) {
				++j;
				p = p->next;
			}
		}
		else {
			p = l->next;
			while (p->next != NULL && j!=i) {
				++j;
				p = p->next;
			}
		}
		cout << i << "位置的元素是:" << p->data << endl; 
	}
}
//取位置i的前驱元素
void linkedListPrior(LinkedList l, int i) {
	if (i<1 || i> linkedListLength(l)) cout << "超出顺序表长度!请重新输入!" << endl;
	else if(i == 1) cout<<"首元素没有前驱!"<<endl;
	else {
		int j = 0;
		LinkedList p;
		if (l->data != NULL) {
			p = l;
			while (p->next != NULL && j!=i-1) {
				++j;
				p = p->next;
			}
		}
		else {
			p = l->next;
			while (p->next != NULL && j != i - 1) {
				++j;
				p = p->next;
			}
		}
		cout << "位置:" << i << "的前驱元素为:" << p->data << endl;
	}
}
//取位置i的后继元素
void linkedListNext(LinkedList l, int i) {
	if (i<1 || i> linkedListLength(l)) cout << "超出顺序表长度!" << endl;
	else if (i == linkedListLength(l)) cout<<"尾元素没有后驱!"<<endl;
	else {
		int j = 0;
		LinkedList p;
		if (l->data != NULL) {
			p = l;
			while (p->next != NULL && j != i + 1) {
				++j;
				p = p->next;
			}
		}
		else {
			p = l->next;
			while (p->next != NULL && j != i + 1) {
				++j;
				p = p->next;
			}
		}
		cout << "位置" << i << "的后驱是:" << p->data << endl;
	}
}
//元素x在L中的位置
void linkedListLocate(LinkedList l, dataType x) {
	int i = 0;
	LinkedList p;
	if (l->data != NULL) {
		p = l;
		while (p->next != NULL && p->data != x) {
			++i;
			p = p->next;
		}
	}
	else {
		p = l->next;
		while (p->next != NULL && p->data != x) {
			++i;
			p = p->next;
		}
	}
	if (i <= linkedListLength(l)) cout<<x<<"在表中的位置是:"<<i<<endl;
	else cout<<"不在表中"<<endl;
}
//在表L的位置i处插入元素x
LinkedList linkedListInsert(LinkedList l,int i,dataType x) {
	int j = 1;
	LinkedList pri=l,s=l;
	LinkedList p = (LNode*)malloc(sizeof(LNode));
	p->data = x;
	if (l->data > 0) {
		if (i == 1) {
			p->next = l;
			cout << "插入成功!" << endl;
			return p;
		}
		else while (j != i + 1) {
			pri = s;
			s = s->next;
			++j;
		}
		pri->next = p;
		p->next = s;
	}
	else {
		while (j != i + 1) {
			pri = s;
			s = s->next;
			++j;
		}
		pri->next = p;
		p->next = s;
	}
	cout << "插入成功!" << endl;
	return l;
}
//删除位置i处的元素
LinkedList linkedListDelete(LinkedList l,int i) {
	int j = 1;
	LinkedList pri = l, p = l;
	if (i<1 || i> linkedListLength(l)) {
		cout << "超出顺序表长度!" << endl; 
		return l;
	}
	if (l->data > 0) {
		if (i == 1) {
			p = p->next;
			free(pri);
			cout << "删除成功!" << endl;
			return p;
		}
		else while (i != j) {
			pri = p;
			p = p->next;
			++j;
		}
		pri->next = p->next;
		free(p);
	}
	else {
		p = p->next;
		if (i == 1) {
			pri = p;
			p = p->next;
			l->next = p;
			free(pri);
		}
		else {
			while (i != j) {
				pri = p;
				p = p->next;
				++j;
			}
			pri->next = p->next;
			free(p);
		}
	}
	cout << "删除成功!" << endl;
	return l;
}
//表是否为空
void linkedListEmpty(LinkedList l) {
	if (l->next==NULL) {
		cout << "是空表!" << endl;
	}
	else cout << "不是空表!" << endl;
}
//清空表
LinkedList linkedListClear(LinkedList l) {
	LinkedList p,r;
	p = l->next;
	while (p!= NULL) {
		r = p->next;
		free(p);
		p = r;
	}
	l->next=NULL;
	l->data = NULL;
	cout << "清空完成!" << endl;
	return l;
}
//遍历输出所有元素
void linkedListTraverse(LinkedList l) {
	LinkedList p=l;
	if (linkedListLength(l) != 0) {
		cout << "遍历结果是:";
		if (l->data > 0) {
			while (p->next != NULL) {
				cout << p->data << " ";
				p = p->next;
			}
			cout << p->data;
		}
		else {
			p = p->next;
			while (p->next != NULL) {
				cout << p->data << " ";
				p = p->next;
			}
		}
		cout << p->data;
		cout << endl;
	}
	else {
		cout << "空表不能遍历!" << endl;
	}
}
//将位置i的元素修改为x
LinkedList sqlListUpdate(LinkedList l,int i,dataType x) {
	LinkedList p=l;
	int j = 1;
	if (i<1 || i> linkedListLength(l)) {
		cout << "超出顺序表长度!" << endl;
		return l;
	}
	if(l->data > 0){
	    while (i != j) {
			p = p->next;
			++j;
		}
		p->data = x;
	}
	else {
		p = p->next;
		while (i != j) {
			p = p->next;
			++j;
		}
		p->data = x;
	}
	cout << "修改成功!" << endl;
	return l;
}
void print() {
	cout <<	"*********************************************"<<endl;
	cout <<	"*	1.链表的长度		   2.取位置i的前驱	 *"<< endl;
	cout <<	"*	3.取位置i的后驱		   4.元素x的位置	 *"<< endl;
	cout <<	"*	5.位置i处插入元素x	   6.删除位置i的元素 *"<< endl;
	cout << "*	7.取位置i的元素		   8.表是否为空		 *"<< endl;
	cout << "*	9.清空表			   10.遍历表		 *"<< endl;
	cout << "*	11.修改位置i的元素	   12.退出    		 *"<< endl;
	cout << "*	13.清空命令行		   14头插法	   		 *"<< endl;
	cout << "*	15.尾插法(带头结点)  16尾插法(不带头)*" << endl;
	cout << "*********************************************"<< endl;
}
void main() {
	int m=0,i = 0,n=0;
	LinkedList l = linkedListCreateT();
	print();
	while (1) {
		cin >> i;
		switch (i)
		{
		case 1:cout <<"链表的长度为:"<<linkedListLength(l) << endl; break;
		case 2:cin >> m;linkedListPrior(l, m); break;
		case 3:cin >> m; linkedListNext(l, m); break;
		case 4:cin >> m; linkedListLocate(l, m); break;
		case 5:cin >> m >> n;l=linkedListInsert(l, m, n); break;
		case 6:cin >> m;l=linkedListDelete(l, m); break;
		case 7:cin >> m; linkedListGet(l, m);break;
		case 8:linkedListEmpty(l);break;
		case 9:l = linkedListClear(l);break;
		case 10:linkedListTraverse(l);break;
		case 11:cin >> m; cin >> n;l = sqlListUpdate(l,m,n); break;
		case 12:exit(0);
		case 13:system("cls"); print();break;
		case 14:l = linkedListCreateT(); break;
		case 15:l = linkedListCreateW1(); break;
		case 16:l = linkedListCreateW2(); break;
		default:cout << "数字超出范围,请重新输入。" << endl; break;
		}
	}
}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值