[C++]单链表的相关操作(v2.0版-完整)

好几天没有码了,今天弄好了自习室,继续了考研复习,晚上回来敲一敲代码,单链表的相关操作都整理了,后续在码双链表,循环链表等的函数,不过和单链表相比大同小异,甚至更加方便

头文件一共包含如下操作:

  1. 单链表节点定义LNode
  2. 求表长getLength
  3. 在给定指针p前面插入结点frontInsert
  4. 在给定指针p后面插入结点behindInsert
  5. 头插法函数head_insert,手动输入
  6. 尾插法函数tail_insert,手动输入
  7. 给空表自动赋值auto_assignment
  8. 遍历函数printList
  9. 判空函数emptyList
  10. 按值查找locateElem
  11. 按位查找getElem
  12. 删除节点deleteElem

个人认为这些操作里边比较精彩的是3.在指针p之前插入节点和12.删除节点。3涉及一个时间复杂度的优化,偷梁换柱,o(n)->o(1);12涉及一个细节的处理,如果删除的节点是链表最后一位,则必须单独处理,否则会报错,因为无法将末尾的指针变为NULL,这会影响求表长以及遍历函数的使用,因这些函数都是靠NULL来判断链表的结束的。

代码如下:

#include<iostream>
using namespace std;

#define MAX 25//用于控制链表的最大表长
//带头结点的单链表操作

//定义单链表结点
struct LNode {
	int data;
	LNode* next;
};

//求表长getLength
int getLength(const LNode* L) {
	int i = 0;
	LNode* s = (LNode*)(L->next);
	while (i < MAX) {
		if (s == NULL)break;
		i++;
		s = s->next;
	}
	return i;
}

//在给定指针p前面插入结点
bool frontInsert(LNode* p,int e) {
	LNode *s = (LNode*)malloc(sizeof(LNode));
	if (s == NULL)return false;

	s->data = p->data;
	s->next = p->next;
	p->next = s;
	p->data = e;

	return true;
}

//在给定指针p后面插入结点
bool behindInsert(LNode* p,int e) {

	LNode *s = (LNode*)malloc(sizeof(LNode));
	if (s == NULL)return false;
	s->data = e;
	//两步插入节点
	s->next = p->next;
	p->next = s;
	return true;
}

//头插法函数head_insert,手动输入,初始链表为空
//输入-1代表结束输入
bool head_insert(LNode* L) {
	L->next = NULL;
	LNode* s;
	int x;
	while (1) {
		cin >> x;
		if (x == -1)break;
		s = (LNode*)malloc(sizeof(LNode));
		if (s == NULL  )return false;
		s->next = L->next;
		L->next = s;
		s->data = x;
	}
	return true;
}

//尾插法函数tail_insert,手动输入,初始链表为空
bool tail_insert(LNode* L) {
	L->next = NULL;
	int x=0;
	LNode *s = L;//s指向最后一个节点
	while (1) {//输入-1结束插入操作
		cin >> x;
		if (x == -1)break;
		s->next = (LNode*)malloc(sizeof(LNode));
		if (s == NULL)return false;
		s->next->data = x;
		s->next->next = NULL;
		s = s->next;
	}
	return true;
}

//给空表自动赋值auto_assignment
//单链表L,num表示自动尾插的节点个数
bool auto_assignment(LNode* L, int num=20) {
	if (num<1||num > MAX||L->next!=NULL) return false;
	LNode *s = L;//s指向最后一个节点

	for (int i = 0; i < num;i++) {
		s->next = (LNode*)malloc(sizeof(LNode));
		s->next->next = NULL;
		s->next->data = rand() % 100;
		s = s->next;
	}
	return true;
}

//遍历函数printList
bool printList(const LNode* L) {
	if (L->next == NULL)return false;
	LNode*s = L->next;
	int i = 0;
	while(s!=NULL) {
		cout << s->data << " " ;
		s = s->next;
		if (i % 10 == 9)cout << endl;
		i++;
	}
	cout << endl;
	return true;
}

//判空函数
bool emptyList(const LNode* L) {
	if (L->next == NULL) {
		return true;
	}
	return false;
}

//按值查找locateElem
//查找成功返回指针,失败返回NULL
LNode* locateElem(const LNode* L, int e) {
	LNode* s = (LNode*)L->next;
	if (s == NULL) {//表空则直接结束,NULL
		return NULL;
	}
	for (int i = 1; i <= getLength(L);i++) {
		if (e == s->data)return s;//成功则返回指针
		s = s->next;
	}
	return NULL;//未找到则返回NULL
}
//按位查找getElem,查找第i个元素
//成功:返回结点指针,失败:返回NULL;
LNode *getElem(const LNode* L,int i) {
	LNode* s = (LNode *)(L->next);
	if (i<1||i>getLength(L)) {//i的范围不合理
		return NULL;
	}
	else {
		for (int j = 1; j <i;j++) {//向后遍历
			s = s->next;
		}
		return s;
	}
}

//删除节点操作
//给定一个节点的指针,删除该指针指向的节点
bool deleteElem(const LNode* L, LNode* p) {
	if(p->next!=NULL){
		p->data = p->next->data;
		p->next = p->next->next;
		free(p->next);
		
	}
	else {//如果删除的节点是链表最后一个,那么需要从表头开始遍历
		LNode* s = L->next;
		for (int i = 1; i < MAX;i++) {
			if (s->next==p) {
				s->next = NULL;
				free(p);
				break;
			}
			s = s->next;
		}
	}	
	return true;
}




疲惫,准备洗洗睡了。。。。。。

加油奥力给~~~~~~~~~~~~~

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值