数据结构--单链表

功能
1-----初始化或重置链表
2-----销毁单链表
3-----清空单链表
4-----求单链表长度
5-----获取单链表中指定位置的元素
6-----获取单链表指定元素的位序
7-----求输入元素的直接前驱
8-----求输入元素的直接后继
9-----在单链表第i个位置插入元素
10----删除单链表第i个位置的元素
11----输出单链表所有的的元素
12----初始化并用头插法输入元素
13----初始化并用尾插法输入元素
14----实现单链表的逆序存放
15----判断单链表是否为空

#include <iostream>
#include<stdlib.h>
#include<stdio.h>
using namespace std;
//错误代码
#define OK 1
#define ERROR 0
//统一程序中数据形式,便于一次性更改链表存储数据的数据类型
typedef int ElemType;
typedef int Status;

typedef struct Node {   //定义节点的结构 数据类型node 初始有一个linklist指针指向没有初始化的链表
	ElemType data;
	struct Node *next;
} Node, *LinkList;

//1初始化链表
Status InitList(LinkList &L) {
	L = (Node*)malloc(sizeof(Node)); //申请空间并看看是否成功
	if (L == NULL) return ERROR;
	L->next = NULL; //next节点指向空
	return OK;
}

//2销毁单链表
Status DestoryList(LinkList &L) {
	Node *p;
	p = L;
	while (p) { //设置一个指针p与头指针相投,依次断开头部节点,用p做指引释放断开节点的内存,然后将p再次指向头指针,直到所有的节点被释放(while循环驱动),最后p指向为被销毁的链表(只剩下指向空的头指针),即空
		L = L->next;
		free(p);
		p = L;
	}
	return OK;
}

//3清空单链表
Status ClearList(LinkList &L) {
	Node *p, *q; //两个指针,一个p指向头指针后第一个节点,另一个q指向p后面的元素,不断释放p所指向的元素,然后p指向q,q后移,使用while循环重复,直到到达链表尾,最后把头指针指向为空即完成清除
	p = L->next;
	while (p) {
		q = p->next;
		free(p);
		p = q;
	}
	L->next = NULL;
	return OK;
}

//4求单链表长度
Status LengthList(LinkList L) { //两个指针一前一后,互相赋值,同时每次前进i自增。p在后,q在前,当p走到单链表的尾部时,退出循环,返回i的值,即长度
	Node *p, *q;
	int i = 0;
	p = L;
	while (p->next) {
		q = p->next;
		p = q;
		i++;
	}
	return i;
}

//单链表读取功能函数:当第i个元素存在时,其值赋给e并返回OK,否则返回ERROR
Status GetELem_List(LinkList L, int i, ElemType &e) {
	Node *p;
	int j = 1;
	p = L->next;
	while (p && j < i) { //!p即p为空,有两种情况,第一种是表为空;第二种是i的值超过了表的长度,while循环执行完后p走到最后一个元素还没有找到i的位置。j >i 就是i是0或者负数的情况
		p = p->next;
		++j;
	}
	if (!p || j > i)
		return ERROR;
	e = p->data;
	return OK;
}

//5 输入位置找元素
void SearchElementFromList(LinkList L, int i) {
	ElemType result_temp; //
	if (GetELem_List(L, i, result_temp)) { //调用GetELem_List函数即可
		cout << "第" << i << "个元素的值是 " << result_temp << endl;
	} else {
		cout << "第" << i << "个元素不存在,当然也没有值 " << endl;
	}
}

//6 输入元素找位置
Status SearchLocationFromListh(LinkList L, int &i, ElemType e) { // 表 元素的位置 元素值
	Node *p, *q;
	i = 1;
	p = L->next; //双指针遍历整个单链表,依次对比元素值,发现相同的直接结束函数返回对应位置即可,若遍历完成还没有找到元素,返回error错误提示
	while (p) {
		if (p->data == e) {
			return OK;
		}
		i++;
		q = p->next;
		p = q;
	}
	return ERROR;
}

//7 求前驱
Status BeforeList(LinkList L, ElemType &e) {
	int i;
	Node *p, *q;
	p = L;
	if (!SearchLocationFromListh(L, i, e)) { //找不到元素
		cout << "压根没有的元素找什么?" << endl;
		return ERROR;
	} else if (i == 1) { //第一个元素没有前驱
		cout << "这第一个元素压根就没有前驱找什么?" << endl;
		return ERROR;
	} else {
		for (int j = 0; j < i - 1; j++) { //直接到第i-1个元素位置
			q = p->next;
			p = q;
		}
		e = p->data;
		return OK;
	}

}

//8 求后继
Status AfterList(LinkList L, ElemType &e) {
	int i;
	Node *p, *q;
	p = L;
	if (!SearchLocationFromListh(L, i, e)) {
		cout << "压根没有的元素找什么?" << endl;
		return ERROR;
	} else if (i == LengthList(L)) {
		cout << "这最后一个元素压根就没有前驱找什么?" << endl;
		return ERROR;
	} else {
		for (int j = 0; j < i + 1; j++) {
			q = p->next; //直接到第i-1个元素位置
			p = q;
		}
		e = p->data;
		return OK;
	}
}
//9 在单链表第i个位置插入元素
Status ListInsert(LinkList &L, int i, ElemType e) {
	Node *p, *s; //初始化指向,p最后指向插入位置
	int j = 1;
	p = L;
	while (p && j < i) { //遍历到第i个位置
		p = p->next;
		j++;
	}
	if (!p || j > i) //第i个位置是否合法? 非空
		return ERROR;
	s = (LinkList)malloc(sizeof(Node)); //分配新空间 插入
	s-> data = e;
	s->next = p->next;
	p->next = s;
	return OK;
}
//10 删除第i个元素
Status ListDelete(LinkList &L, int i) {
	Node *p, *s; //初始化指向,p最后指向删除位置前一个节点,s是被删除的
	int j = 1;
	p = L;
	while (p->next && j < i) { //遍历到第i-1个位置
		p = p->next;
		j++;
	}
	if (!p->next || j > i) //第i-1个位置是否合法? 非空
		return ERROR;
	s = p->next;
	p->next = s->next;
	free(s);
	return OK;
}
//11 输出所有元素
Status OutputList(LinkList L) {
	Node *p;
	p = L;
	while (p->next != NULL) { //遍历,直到指向为空
		p = p->next;
		cout << p->data << " ";
	}
	cout << endl;
	return OK;
}
//12 初始化 头插法
Status LinkCreate_head(LinkList &L, int m) { //有多少个插入的元素
	Node *p;
	L = (LinkList)malloc(sizeof(Node));
	L->next = NULL; //初始化表
	for (m = m; m > 0; m--) {
		p = (LinkList)malloc(sizeof(Node));
		cin >> p->data;
		p->next = L->next; //指针操作,把p放在表l的头部
		L->next = p;
	}
	return OK;
}
//13 初始化 尾插法
Status LinkCreate_tail(LinkList &L, int m) { //有多少个插入的元素
	Node *p, *q;
	L = (LinkList)malloc(sizeof(Node));
	L->next = NULL; //初始化表
	p = L; //p指向表l
	for (int i = 0; i < m; i++) {
		q = (LinkList)malloc(sizeof(Node)); //q是待插入的元素
		cin >> q->data; //插入元素
		q->next = NULL;
		p->next = q; //把q连接在p的后面,p再向前走一个
		p = p->next;
	}
	return OK;
}
//14 逆置
Status ListInverse(LinkList &L) {
	Node *p, *q;
	p = L->next;        //p指向表中第一个结点
	L->next = NULL;      //头结点为空
	while (p) {
		q = p;               //q指到p的位置
		p = p->next;          //p指向下一个
		q->next = L->next;   //让q指向头结点指向的位置
		L->next = q;          //头结点指向q
	}
	return OK;

}

int main() {
	int n = 1;			 //退出菜单的标记
	int s;				 //功能选择
	int ListChecked = 0; // 链表是否存在检查
	int a, b, i, result; //临时用的变量
	LinkList L;
	cout << "===欢迎使用单链表实验功能小程序 (^_?)☆" << endl;
	cout << "1-----初始化或重置链表" << endl;
	cout << "2-----销毁单链表" << endl;
	cout << "3-----清空单链表" << endl;
	cout << "4-----求单链表长度" << endl;
	cout << "5-----获取单链表中指定位置的元素" << endl;
	cout << "6-----获取单链表指定元素的位序" << endl;
	cout << "7-----求输入元素的直接前驱" << endl;
	cout << "8-----求输入元素的直接后继" << endl;
	cout << "9-----在单链表第i个位置插入元素" << endl;
	cout << "10----删除单链表第i个位置的元素" << endl;
	cout << "11----输出单链表所有的的元素" << endl;
	cout << "12----初始化并用头插法输入元素" << endl;
	cout << "13----初始化并用尾插法输入元素" << endl;
	cout << "14----实现单链表的逆序存放" << endl;
	cout << "15----判断单链表是否为空" << endl;
	cout << "===退出,输入一个负数!===========" << endl;

	while (n) {
		//n不等于0

		cout << "请输入指令编号(1--13),(退出时输入负数):\n";
		scanf("%d", &s);
		if (ListChecked == 0 && s != 1 && s != 15) {
			cout << "请先初始化一个单链表" << endl;
			continue;
		}
		switch (s) {
			case 1:
				if (InitList(L)) {
					ListChecked = 1;
					cout << "单链表初始化成功!" << endl;
				} else {
					cout << "错误,单链表初始化失败,请重试!" << endl;
				}
				break;

			case 2:
				if (DestoryList(L)) {
					cout << "单链表销毁完成!" << endl;
					ListChecked = 0;
				}
				break;

			case 3:
				if (ClearList(L))
					cout << "单链表清空完成!" << endl;
				break;

			case 4:
				cout << "单链表长度为" << LengthList(L) << endl;
				break;

			case 5:
				cout << "输入位置找元素:";
				cin >> a;
				SearchElementFromList(L, a);
				break;
			case 6:
				ElemType temp_6; //声明一个临时变量,存放呆查找元素的值
				cout << "输入元素找位置:";
				cin >> temp_6;
				result = SearchLocationFromListh(L, i, temp_6);
				if (result == ERROR)
					cout << "此元素不存在呀!" << endl;
				else
					cout << "为您找到元素" << temp_6 << "的位置是:" << result << endl;
				break;
			case 7:
				ElemType temp_7; //声明一个临时变量,存放待求前驱元素的值
				cout << "输入要求前驱的元素 :";
				cin >> temp_7;
				cout << "元素" << temp_7 << "的前驱是:";
				result = BeforeList(L, temp_7);
				if (result != ERROR)
					cout << temp_7 << endl;
				break;
			case 8:
				ElemType temp_8; //声明一个临时变量,存放待求后继元素的值
				cout << "输入要求后继的元素 :";
				cin >> temp_8;
				cout << "元素" << temp_8 << "后继是:";
				result = AfterList(L, temp_8);
				if (result != ERROR)
					cout << temp_8 << endl;
				break;
			case 9:
				ElemType temp_9;
				cout << "在第几个位置插入?" << endl;
				cin >> i;
				cout << "输入插入的元素" << endl;
				cin >> temp_9;
				if (ListInsert(L, i, temp_9))
					cout << "成功插入!" << endl;
				else
					cout << "插入失败!检查输入的位置合法性!" << endl;
				break;
			case 10:
				cout << "在第几个位置删除?" << endl;
				cin >> b;
				if (ListDelete(L, b))
					cout << "删除成功!" << endl;
				else
					cout << "删除失败,检查删除位置合法性!"  << endl;
				break;
			case 11:
				cout << "将输出表中所有元素:" << endl;
				OutputList(L);
				break;
			case 12:
				cout << "初始化表并插入元素(头插法),请输入要插入多少个元素" << endl;
				cin >> a;
				if (LinkCreate_head(L, a))
					cout << "插入完成!" << endl;
				break;
			case 13:
				cout << "初始化表并插入元素(尾插法),请输入要插入多少个元素" << endl;
				cin >> a;
				if (LinkCreate_tail(L, a))
					cout << "插入完成!" << endl;
				break;
			case 14:
				ListInverse(L);
				cout << "逆置操作完成!" << endl;
			case 15:	
				if( LengthList(L))
				cout << "表是空的"  << endl;
				else
				cout << "表不是空的"  << endl;
				break;
			default:

				if (s < 0) {
					n = 0;
					cout << "程序退出成功,欢迎下次使用~~" << endl;
					break;
				} else
					cout << "您输入的指令有误,请重新输入~" << endl;

		} //switch

	} //while

} //main

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值