数据结构-单链表

一、链表初始化

typedef struct LNode
{
	int data;
	struct LNode *next;
} LNode, *LinkList;
// 链表初始化
bool ListInit(LinkList &L)
{

	L = (LNode *)malloc(sizeof(LNode));
	if (L == NULL)
	{
		perror("malloc LNode fault\n");
		return false;
	}
	L->next = NULL;
	return true;
}

二、链表的插入

(1)按位序插入
// 按位序插入,指插入节点为第n个节点
bool ListNodeInsert(LinkList &L, int i, int elem)
{
	if (i < 1)
	{
		perror("insert element falut: i < 1");
		return false;
	}
	LNode *p = FindNode(L, i - 1);

	return InsertNode(p, elem);
}
 (2)第i个节点之后插入
// 第i个节点之后插入一个新的节点
bool InsertNextNode(LinkList &L, int i, int elem)
{
	if (i < 1)
	{
		perror("insert element falut: i < 1");
		return false;
	}

	LNode *p = FindNode(L, i);

	return InsertNode(p, elem);
}
(3)指定节点前面插入
// 在指定节点前面插入一个节点
bool InsertFrontNode(LinkList &L, int i, int elem)
{
	if (i < 1)
	{
		perror("insert element falut: i < 1");
		return false;
	}
	LNode *p = FindNode(L, i);

	if (p == NULL)
	{
		perror("insert i Illegal");
		return false;
	}
	LNode *s = (LNode *)malloc(sizeof(LNode));
	if (s == NULL)
	{
		perror("Malloc LNode fault");
		return false;
	}
	s->next = p->next;
	s->data = p->data;
	p->next = s;
	p->data = elem;
	return true;
}
(4)插入节点详细描述
// 插入节点详细步骤
bool InsertNode(LNode *p, int elem)
{
	if (p == NULL)
	{
		perror("insert i Illegal");
		return false;
	}
	LNode *s = (LNode *)malloc(sizeof(LNode));
	if (s == NULL)
	{
		perror("Malloc LNode fault");
		return false;
	}
	s->data = elem;
	s->next = p->next;
	p->next = s;
	return true;
}

三、查找

(1)按位序查找
// 按位序查找
bool GetElem(LinkList &L, int i, int &elem)
{
	if (i < 1)
	{
		perror("GetElem falut: i < 1");
		return false;
	}
	LNode *p = FindNode(L, i);
	if (p == NULL)
	{
		perror("Getelem's Node i Illegal");
		return false;
	}
	elem = p->data;
	return true;
}
(2)按值查找
// 按值查找
LNode *FindElem(LinkList &L, int elem)
{
	LNode *p = L->next;
	while (p != NULL && p->data != elem)
	{
		p = p->next;
	}
	return p;
}
(3)查找指定节点
// 查找指定节点
LNode *FindNode(LinkList &L, int i)
{
	int k = 0;
	LNode *p = L;
	while (p != NULL && k < i)
	{
		p = p->next;
		k++;
	}
	return p;
}

四、删除节点

(1)按位序删除节点
// 按位序删除节点
bool DeleteNode(LinkList &L, int i, int &elem)
{
	if (i < 1)
	{
		perror("insert element falut: i < 1");
		return false;
	}
	LNode *p = FindNode(L, i - 1);
	if (p == NULL || p->next == NULL)
	{
		perror("delete i Illegal");
		return false;
	}
	LNode *q = p->next;
	elem = q->data;
	p->next = q->next;
	free(q);
	return false;
}
(2)删除指定节点
// 删除指定节点
bool DeletePointNode(LinkList &L, int i, int &elem)
{
	if (i < 1)
	{
		perror("insert element falut: i < 1");
		return false;
	}
	LNode *p = FindNode(L, i);
	if (p == NULL)
	{
		perror("delete i Illegal");
		return false;
	}
	elem = p->data; // 获取指定节点的数据

	LNode *q = p->next; // 找到指定节点的后继节点
	p->data = q->data;	// 将后继节点的数据复制到指定节点p
	p->next = q->next;	// 让指定节点p的next指向原本后继节点的下一个节点
	// 这里就相当于把指定节点的后继节点给覆盖到指定节点
	free(q);
	return true;
}

五、计算链表长度及输出

 (1)计算
// 计算链表长度
void ClacListlength(LinkList L)
{
	int length = 0;
	LNode *p = L;
	while(p->next)
	{
		length++;
		p = p->next;
	}
	printf("List length is %d\n",length);
}
(2)输出
// 输出链表
void ListPrint(LinkList L)
{
	LNode *p = L->next;
	while (p != NULL)
	{
		printf("%d\n", p->data);
		p = p->next;
	}
}

六、整体代码演示

/*
	此链表的操作基于带头节点的操作
	不带头节点的操作,在插入第一个节点操作需做特殊处理
	不带头节点除第一个节点外其它操作与带头节点一致
	需注意的是当前p指向的是第一个节点
*/
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>

typedef struct LNode
{
	int data;
	struct LNode *next;
} LNode, *LinkList;

// 链表初始化
bool ListInit(LinkList &L)
{

	L = (LNode *)malloc(sizeof(LNode));
	if (L == NULL)
	{
		perror("malloc LNode fault\n");
		return false;
	}
	L->next = NULL;
	return true;
}

// 插入节点详细步骤
bool InsertNode(LNode *p, int elem)
{
	if (p == NULL)
	{
		perror("insert i Illegal");
		return false;
	}
	LNode *s = (LNode *)malloc(sizeof(LNode));
	if (s == NULL)
	{
		perror("Malloc LNode fault");
		return false;
	}
	s->data = elem;
	s->next = p->next;
	p->next = s;
	return true;
}

// 查找指定节点
LNode *FindNode(LinkList &L, int i)
{
	int k = 0;
	LNode *p = L;
	while (p != NULL && k < i)
	{
		p = p->next;
		k++;
	}
	return p;
}

// 按位序插入,指插入节点为第n个节点
bool ListNodeInsert(LinkList &L, int i, int elem)
{
	if (i < 1)
	{
		perror("insert element falut: i < 1");
		return false;
	}
	LNode *p = FindNode(L, i - 1);

	return InsertNode(p, elem);
}

// 第i个节点之后插入一个新的节点
bool InsertNextNode(LinkList &L, int i, int elem)
{
	if (i < 1)
	{
		perror("insert element falut: i < 1");
		return false;
	}

	LNode *p = FindNode(L, i);

	return InsertNode(p, elem);
}

// 在指定节点前面插入一个节点
bool InsertFrontNode(LinkList &L, int i, int elem)
{
	if (i < 1)
	{
		perror("insert element falut: i < 1");
		return false;
	}
	LNode *p = FindNode(L, i);

	if (p == NULL)
	{
		perror("insert i Illegal");
		return false;
	}
	LNode *s = (LNode *)malloc(sizeof(LNode));
	if (s == NULL)
	{
		perror("Malloc LNode fault");
		return false;
	}
	s->next = p->next;
	s->data = p->data;
	p->next = s;
	p->data = elem;
	return true;
}

// 按位序删除节点
bool DeleteNode(LinkList &L, int i, int &elem)
{
	if (i < 1)
	{
		perror("insert element falut: i < 1");
		return false;
	}
	LNode *p = FindNode(L, i - 1);
	if (p == NULL || p->next == NULL)
	{
		perror("delete i Illegal");
		return false;
	}
	LNode *q = p->next;
	elem = q->data;
	p->next = q->next;
	free(q);
	return false;
}

// 删除指定节点
bool DeletePointNode(LinkList &L, int i, int &elem)
{
	if (i < 1)
	{
		perror("insert element falut: i < 1");
		return false;
	}
	LNode *p = FindNode(L, i);
	if (p == NULL)
	{
		perror("delete i Illegal");
		return false;
	}
	elem = p->data; // 获取指定节点的数据

	LNode *q = p->next; // 找到指定节点的后继节点
	p->data = q->data;	// 将后继节点的数据复制到指定节点p
	p->next = q->next;	// 让指定节点p的next指向原本后继节点的下一个节点
	// 这里就相当于把指定节点的后继节点给覆盖到指定节点
	free(q);
	return true;
}

// 按位序查找
bool GetElem(LinkList &L, int i, int &elem)
{
	if (i < 1)
	{
		perror("GetElem falut: i < 1");
		return false;
	}
	LNode *p = FindNode(L, i);
	if (p == NULL)
	{
		perror("Getelem's Node i Illegal");
		return false;
	}
	elem = p->data;
	return true;
}

// 按值查找
LNode *FindElem(LinkList &L, int elem)
{
	LNode *p = L->next;
	while (p != NULL && p->data != elem)
	{
		p = p->next;
	}
	return p;
}

// 计算链表长度
void ClacListlength(LinkList L)
{
	int length = 0;
	LNode *p = L;
	while(p->next)
	{
		length++;
		p = p->next;
	}
	printf("List length is %d\n",length);
}

// 输出链表
void ListPrint(LinkList L)
{
	LNode *p = L->next;
	while (p != NULL)
	{
		printf("%d\n", p->data);
		p = p->next;
	}
}

int main()
{
	LinkList L;
	ListInit(L);
	for (int i = 1; i <= 10; i++)
	{
		ListNodeInsert(L, i, i);
	}
	// 指定节点之后插入一个新的节点
	InsertNextNode(L, 2, 6);

	// 指定节点之前插入一个新的节点
	InsertFrontNode(L, 4, 5);
	ListPrint(L);

	// 删除指定节点并返回指定节点的数据
	int elem = 0;
	DeleteNode(L, 4, elem);
	printf("Deleted data is %d Node\n", elem);
	ListPrint(L);

	// 删除指定节点(方法二)并返回指定节点的数据
	DeletePointNode(L, 2, elem);
	printf("Deleted data is %d Node\n", elem);
	ListPrint(L);

	// 获取节点数据
	GetElem(L, 2, elem);
	printf("No.2 Node's data is %d\n", elem);

	// 查找链表中是否存在数据elem
	if (FindElem(L, 8))
	{
		printf("exist Node\n");
	}
	else
	{
		printf("Can't find eNode\n");
	}
	ClacListlength(L);

	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值