数据结构---链表


链表原理就不过多解释了,直接代码中理解吧

单向链表算法实现

1.数据类型定义

在这里插入图片描述

typedef struct _LinkNode
{
	int data; //数据
	struct _LinkNode* next;  //下一节点指针
}LinkNode, LinkList; //两个别名

2.初始化空表

bool InitList(LinkList* &L)
{
	L = new LinkNode;
	if (!L) return false;

	L->next = NULL;
	return true;
}

3.前插法

①空链表

在这里插入图片描述

②插入第一个节点

在这里插入图片描述

③插入第二个节点

在这里插入图片描述
具体操作如下图
头结点指向节点2,结点2指向节点1
头结点L指向A1, 这个链接赋值给新节点即可
New->next = L->next

头结点在连上新节点
L->next = New
在这里插入图片描述

/*前插法*/
bool ListInsert_front(LinkList* &L, LinkNode* node)
{
	if (!L || !node) return false;

	node->next = L->next;
	L->next = node;
}

4.后插法

理解前插,后插也很简单,只需要定义一个临时节点last,用于遍历到链表的末尾,循环条件是节点next为空,找到最后一个节点后,新节点直接链接即可,后插法要把新节点的next指针置为空,方便下次查找
在这里插入图片描述

/*后插法*/
bool ListInsert_back(LinkList*& L, LinkNode* node)
{
	LinkNode* last = NULL;

	if (!L || !node) return false;

	last = L;

	while (last->next)
	{
		last = last->next;
	}
	
	node->next = NULL;
	last->next = node;

	return true;
}

5.任意位置插入数据

在节点2的位置插入方法:
在这里插入图片描述
如下图,遍历到插入点, 新节点next替换为原节点next,原节点连接到新节点.

插入节点的方法跟前插类似,多一步找插入位置的过程.
在这里插入图片描述
通过代码理解,掌握了前插法,这一步就很简单了

/*指定位置插入*/
bool LinkInsert(LinkList*& L, int i, int& e)//插入位置,插入元素
{
	if (!L) return false;
	
	//找到插入位置的前一个节点
	int j = 0;
	LinkList* tmp, * s;
	tmp = L;

	while (j < i - 1 && tmp)  //查找位置为i-1的节点, tmp指向该节点
	{
		tmp = tmp->next;
		j++;
	}

	if (!tmp || j > i - 1)  //插入的位置不对,大于总节点,或小于0
	{
		return false;
	}

	s = new LinkNode;  //新节点
	s->data = e;
	s->next = tmp->next;
	tmp->next = s;

	return true;
}

6.按值查找数据

/*按值获取元素*/
bool Link_FindElem(LinkList* L, int e) //按值查找
{
	//在带头结点的单链表 L 中查找值为 e 的元素LinkList *p;
	LinkList* p;

	p = L->next;

	while (p && p->data != e) {     //顺链域向后扫描,直到 p 为空或 p 所指结点的数据域等于 e
		p = p->next;	                     //p 指向下一个结点
	}
	if (!p)return false;

	return true;
}

7.删除

在这里插入图片描述

/*删除元素*/
bool LinkDelete(LinkList*& L, int i) //单链表的删除
{
	//在带头结点的单链表 L 中,删除第 i 个位置
	LinkList* p, * q;
	int j; 
	p = L; 
	j = 0;

	while ((p->next) && (j < i - 1)) //查找第 i-1 个结点,p 指向该结点
	{
		p = p->next; 
		j++;
	}

	if (!(p->next) || (j > i - 1))//当 i>n 或 i<1 时,删除位置不合理
		return false;

	q = p->next;              //临时保存被删结点的地址以备释放空间
	p->next = q->next;   //改变删除结点前驱结点的指针域delete 
	delete q;                    //释放被删除结点的空间

	return true;
}

8.单链表销毁

/*单链表销毁*/
void LinkDestroy(LinkList* &L)
{
	LinkList* tmp = L;
	cout << "销毁链表" << endl;

	while (tmp)
	{
		L = L->next;
		delete tmp;
		tmp = L;
	}
}

循环链表算法实现

1.数据类型定义

同单链表

2.初始化空表

在这里插入图片描述

bool InitList(LinkList* &L)
{
	L = new LinkNode;

	if (!L) return;
	L->next = L;
	L->data = -1;

	return true;
}

3.尾插法

①空链表插入

在这里插入图片描述

这里注意,代码中判断是否为末尾节点的判定有所更改,原来单链表是判断next是否指向空,现在循环链表判断next是否指向头节点.

②已存在节点插入

在这里插入图片描述
遍历找到链表的末尾结点, 将末尾结点的next指针指向新节点,新节点指向头结点(L)

/*尾插法*/
bool
ListInsert_back(LinkList*& L, LinkNode* node)
{
	LinkNode* last = NULL;

	if (!L || !node) return false;

	if (L == L->next) //空循环链表 (头结点指针域指向自己)
	{
		node->next = L;
		L->next = node;
	}
	else
	{
		/*向下遍历直到末尾 */
		last = L->next;
		while (last->next !=L)  last = last->next;  //定位到尾节点

		//新节点连接到尾部
		node->next = L;
		last->next = node;
	}

	return true;
}

双向链表算法实现

后续补充

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值