单链表及其实现

单链表是一种重要的数据结构,为了防止忘记单链表,写一篇博客用来复习。本文实现了单链表的创建、插入、删除、排序、倒置以及合并等功能,如有遗漏,可以根据单链表的思想自行实现。

单链表采用结构指针来实现,首先定义一个结构体,里面存放数据和指向下一个结点的指针。

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

实现代码

#include <iostream>

typedef struct LNode
{
	int data;  // 数据域
	struct LNode* next;  // 指针域
}LNode, *LinkList;

// 创建空表
LinkList CreateHead()
{
	LinkList head = (LinkList)malloc(sizeof(LNode));
	head->next = NULL;
	return head;
}

// 头插法创建链表
LinkList CreateList_Head()
{
	int i, j;
	LinkList h = CreateHead();

	printf("Please input the number of element: ");
	scanf("%d", &j);

	for (i = 0; i < j; ++i)
	{
		LinkList p = (LinkList)malloc(sizeof(LNode));  
		p->data = rand() % 100;  // 也可以修改为用户输入
		p->next = h->next;
		h->next = p;
	}
	return h;
}

// 尾插法创建链表
LinkList CreatList_Tail()
{
	int i, j;
	LinkList h = CreateHead();
	LinkList q = h;

	printf("Please input the number of element: ");
	scanf("%d", &j);

	for (i = 0; i < j; ++i) {
		LinkList p = (LinkList)malloc(sizeof(LNode));
		p->data = rand() % 100;
		printf("%d ", p->data);
		q->next = p;
		q = p;
	}
	q->next = NULL;  // q节点的指针域指向链表尾 
	printf("\n");
	return h;
}

// 遍历链表
void TraverseList(LinkList h) {
	int i = 0;
	LinkList p;
	if (h == NULL)
	{
		printf("Not found list!");
		return;
	}

	p = h->next;
	printf("Linklist elements are: ");
	while (p) {
		printf("%d ", p->data);
		p = p->next;
	}
	printf("\n");
}

// 清空链表
void ClearList(LinkList &h)
{
	LinkList p, q = NULL;
	p = h->next;

	while (p)
	{
		q = p;
		p = p->next;
		free(q);
	}

	h->next = NULL; // 头结点指针域为空
	printf("Linklist has been cleared!\n");
}

// 在第i个位置前插入一个元素
void InsertNode(LinkList &h, int i, int e) {
	int j = 1;
	LinkList p, q;
	p = h; // p指向头结点
	
	while (p && j < i) //寻找第i-1个节点
	{
		p = p->next;
		++j;
	}

	q = (LinkList)malloc(sizeof(LNode));
	q->data = e;
	q->next = p->next;
	p->next = q;
	printf("Successfully insert %d !\n", q->data);
}

// 删除第i个结点
void DeleteNode(LinkList &h, int i)
{
	int j = 1;
	LinkList p, q;
	p = h;
	while (p && j < i) // 和插入一样 先找到第i-1个结点
	{
		p = p->next;
		++j;
	}

	q = p->next;
	p->next = q->next;

	printf("Successfully delete this element%d !\n", q->data);
	free(q);
}

// 查找中间元素
void SearchMidElement(LinkList &h)
{
	int i = 0;
	LinkList p, q;  // q为快指针,p为慢指针
	p = q = h;

	while (q)
	{
		if (q->next->next)  // q的下下个结点存在时
		{
			i++;
			q = q->next->next;
			p = p->next;

			if (q->next == NULL)  // 如果q的下个结点不存在 则结点数为偶数
			{
				printf("Mid elements are: %d, %d\n", p->data, p->next->data);
				break;
			}
		}
		else
		{
			i++;
			printf("Mid elements is: %d\n", p->next->data);
			break;
		}
	}
}

// 翻转链表
void ReverseList(LinkList &h)
{
	LinkList p, q;
	q = h;  // q为前驱指针
	p = h->next;
	h->next = NULL;  // 将h置为空表 重新插入

	while (p)
	{
		q = p;
		p = p->next;
		q->next = h->next;
		h->next = q;
	}
}

// 逆转指针方向 
void ReverseList_p(LinkList &h)
{
	LinkList p, pr, pn; 
	pr = h;
	p = h->next;
	while (p)
	{
		pn = p->next;  // pn 的作用为保存 p 的下一个结点的位置
		p->next = pr; // p 的下一个结点改为前一个结点
		pr = p;  // 指针向后推进
		p = pn;
	}
	if (h->next)  
	{
		h->next->next = NULL;
		h->next = pr;
	}
}

// 升序排序
void SortList(LinkList &h)
{
	LinkList p, q, qr, pr;
	pr = h;
	p = h->next;
	h->next = NULL; // 断开头结点

	while (p)
	{
		pr = p;
		p = p->next;  // 摘掉pr 插入到h中
		qr = h;
		q = h->next;
		while (q && q->data < pr->data) 
		{
			qr = q;
			q = q->next;
		}
		pr->next = q;
		qr->next = pr;
	}
}

// 将两个递增有序排列的链表合并成一个升序序列的链表
void MergeList(LinkList ha, LinkList hb, LinkList &hc)
{
	LinkList pa, pb, pc, p;
	pa = ha->next;
	pb = hb->next;
	pc = hc;

	while (pa && pb)
	{
		if (pa->data < pb->data)  // 如果此时pa的data更小 则摘下结点接到pc上
		{
			p = pa;
			pa = pa->next;
		}
		else
		{
			p = pb;
			pb = pb->next;
		}
		pc->next = p;
		pc = p;
	}

	if (pa) pc->next = pa;
	if (pb) pc->next = pb;
	ha->next = hb->next = NULL;
}

// 删除链表中所有值大于mink且小于maxk的元素
void DeleteElemByRange(LinkList &h, int mink, int maxk)
{
	LinkList p, q, pr;
	if (mink > maxk)return; 
	pr = h;
	p = h->next;

	while (p && p->data < maxk) {
		if (p->data > mink) {
			pr->next = p->next;
			q = p;
			p = p->next;
			free(q);
		}
		else {
			pr = p;
			p = p->next;
		}
	}
}

// 删除升序表中的重复元素 
void DeleteRepeatElem(LinkList &h)
{
	LinkList p, q, pr;
	pr = h;
	p = h->next;
	
	while (p) {
		pr = p;
		p = p->next; // pr和p分别指向第一和第二个节点
		if (p && p->data == pr->data) { // 如果p不为空且pr=p 则删除p
			pr->next = p->next;
			q = p;
			p = p->next;
			free(q);
		}
	}
}

int main()
{
	LinkList L1 = CreateList_Head();
	SortList(L1);
	TraverseList(L1);

	LinkList L2 = CreateList_Head();
	SortList(L2);
	TraverseList(L2);

	LinkList L3 = CreateHead();
	MergeList(L1, L2, L3);
	TraverseList(L3);

	return 0;
}
  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
链栈是基于单链表实现的栈。下面是链栈的基本操作: 1. 初始化链栈:创建一个空链表,将链栈的头指针指向该链表。 2. 判断链栈是否为空:判断链栈的头指针是否为空。 3. 进栈:首先创建一个新节点,将数据存入节点,然后将新节点插入到链表的头部。 4. 出栈:删除链表的头节点,并返回该节点的数据。 5. 清空链栈:遍历链表,逐一删除链表的每个节点。 6. 获取栈顶元素:返回链表的头节点的数据。 下面是链栈的实现代码: ```python class Node: def __init__(self, data=None): self.data = data self.next = None class LinkedStack: def __init__(self): self.top = Node() def is_empty(self): return self.top.next is None def push(self, data): new_node = Node(data) new_node.next = self.top.next self.top.next = new_node def pop(self): if self.is_empty(): raise Exception("Stack is empty!") else: pop_node = self.top.next self.top.next = pop_node.next return pop_node.data def clear(self): self.top.next = None def get_top(self): if self.is_empty(): raise Exception("Stack is empty!") else: return self.top.next.data ``` 其,节点类 Node 包括数据域 data 和指针域 next,表示该节点的下一个节点。链栈类 LinkedStack 包括头指针 top,表示链栈的栈顶元素。is_empty() 方法判断链栈是否为空;push(data) 方法插入新节点;pop() 方法删除链表的头节点;clear() 方法清空链栈;get_top() 方法获取链栈的栈顶元素

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值