[手撕数据结构] 链表及其基本操作

链表是一种物理存储结构上非连续,非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。相比于数组这种连续性的储存结构,链表对于插入及删除等操作将更为方便。

单链表

#include<stdlib.h>
#include<stdbool.h>
#include<iostream>
using namespace std;
struct student
{
	int score;
	struct student* next;
};
typedef struct student stu;
stu* Creat_Node(int x)//申请结点
{
	stu* new_node = new stu;
	new_node->score = x;
	new_node->next = NULL;
	return new_node;
}
void Initlist(stu*& L)//初始化 stu* &L表示对一个指针的引用
{
	L = new stu;
	L->next = NULL;
}

void Insert(int i, int k, stu* L)//在第i个位置插入k;Insert(Get_length(L)+1, 2, L)实现尾插;Insert(1, 2, L);实现头插
{
	stu* o = L;
	for (int j = 1; j < i; j++)
	{
		o = o->next;
	}
	stu* p = new stu;
	p->score = k;
	p->next = o->next;
	o->next = p;
}
void Print_list(stu* head)//遍历打印链表
{
	if (head->next == NULL)
	{
		cout << "空表" << endl;
		return;
	}
	head = head->next;
	while (head)
	{
		cout << head->score << "->";
		head = head->next;
	}
	cout << "NULL" << endl;
	return;
}
void Delete_Kth(stu* list, int k)//删除第k个结点
{
	for (int i = 1; i < k; i++)
	{
		list = list->next;
	}
	stu* p = new stu;
	p = list->next;
	list->next = list->next->next;
	delete p;
	return;
}
int Get_length(stu* list)//获得链表长度
{
	stu* p = list;
	if (p->next == NULL)
	{
		return 0;
	}
	int j = 0;
	p = p->next;
	while (p != NULL)
	{
		p = p->next;
		j++;
	}
	return j;
}
void Find_first(int k, stu* list)//寻找出现值的第一个结点
{
	stu* p = list;
	p = p->next;
	for (int i = 1; i <= Get_length(list); i++)
	{
		if (p->score == k)
		{
			cout << k << "第一次出现的位置为" << i << endl;
			return;
		}
		else
			p = p->next;
	}
	cout << "表中无此值" << endl;
	return;
}
void Find_Kth(int k, stu* list)//寻找第K个结点的值
{
	stu* p = list;
	p = p->next;
	int i = 1;
	while (p->next != NULL && i < k)//p->next==NULL的时候说明此时p已经是最后一个结点
	{
		i++;
		p = p->next;
	}
	if (i == k)
	{
		cout << "第" << k << "个结点的值为" << p->score << endl;
		return;
	}
	else
	{
		cout << "没有第" << k << "个结点" << endl;
		return;
	}

}
void Delete_k(int k, stu* list)//删除所有元素为K的结点
{
	stu* p = list;
	while (p->next)
	{
		if (p->next->score == k)
		{
			stu* q = new stu;
			q = p->next;
			p->next = p->next->next;
			delete q;
		}
		else
			p = p->next;
	}
	return;
}
void sort_list(stu* head)//排序
{
	for (int i = 1; i <= Get_length(head); i++)
	{
		stu* p = head->next;
		for (int j = 1; j < Get_length(head); j++)
		{
			if (p->score > p->next->score)
			{
				int a = p->score;
				p->score = p->next->score;
				p->next->score = a;
			}
			p = p->next;
		}
	}
}
void Merge_list(stu* L, stu* M)//合并链表于L
{
	stu* p = L;
	for (int i = 0; i < Get_length(L); i++)
	{
		p = p->next;
	}
	p->next = M->next;//表尾下接表头
}
void Remove_DupliCation(stu* head)//除去重复元素
{
	stu* p = head->next;
	for (int i = 1; i <Get_length(head); i++)
	{
		if (p->score == p->next->score)
		{
			stu* q = p->next;
			p->next = p->next->next;
			delete q;
		}
		else
			p = p->next;
	}
}
int main()
{
	stu* L;
	Initlist(L);
	stu* M;
	Initlist(M);
	Insert(1, 12, L);
	Insert(1, 7, L);
	Insert(1, 6, L);
	Insert(1, 5, L);
	cout << "L链表: ";
	Print_list(L);
	Insert(1, 11, M);
	Insert(1, 7, M);
	Insert(1, 6, M);
	Insert(1, 3, M);
	Insert(1, 1, M);
	cout << "M链表: ";
	Print_list(M);
	Merge_list(L, M);
	cout << "合并后的链表为:";
	Print_list(L);
	sort_list(L);
	cout << "排序后的链表为:";
	Print_list(L);
	Remove_DupliCation(L);
	cout << "去重后的链表为: ";
	Print_list(L);
	return 0;
}
//嗨害嗨

双向链表

#include<stdlib.h>
#include<stdbool.h>
#include<iostream>
using namespace std;
#define OK 1;
#define ERROR 0;
#define ElemType int;
#define TRUE  1
#define FALSE 0
#define INFEASIBLE  -1
typedef int Status;
struct student
{
	int score;
	struct student* next;
	struct student* last;
};
typedef struct student stu;
Status Initlist(stu* &L)//初始化 stu* &L表示对一个指针的引用
{
	L = new stu;
	L->next = NULL;
	L->last = NULL;
	return OK;
}
Status Insert(int i, int k, stu* L)//在第i个位置插入k;Insert(Get_length(L)+1, 2, L)实现尾插;Insert(1, 2, L);实现头插
{
	stu* o = L;
	for (int j = 1; j < i; j++)
	{
		o = o->next;
	}
	stu* p = new stu;
	p->score = k;
	p->next = o->next;
	p->last = o;
	o->next = p;
	if (p->next != NULL)
	{
      p ->next->last = p;
	}
	
	return OK;
}
Status Print_link(stu* head)//遍历打印链表
{
	if (head->next == NULL)
	{
		cout << "空表" << endl;
		return ERROR;
	}
	head = head->next;
	while (head)
	{
		cout << head->score << endl;
		head = head->next;
	}
	cout << "遍历结束" << endl;
	return OK;
}
Status Delete_Kth(stu* list, int k)//删除第k个结点
{
	for (int i = 1; i < k; i++)
	{
		list = list->next;
	}
	stu* p = new stu;
	p = list->next;
	list->next = list->next->next;
	list->next->last = list;
    delete p;
	return OK;
}
Status Get_length(stu* list)//获得链表长度
{
	stu* p = list;
	if (p->next == NULL)
	{
		return ERROR;
	}
	int j = 0;
	p = p->next;
	while (p!=NULL)
	{
		p = p->next;
		j++;
	}
	return j;
}
Status Find_first(int k, stu* list)//寻找出现值的第一个结点
{
	stu* p = list;
	p = p->next;
	for (int i = 1; i <= Get_length(list); i++)
	{
		if (p->score == k)
		{
			cout << k << "第一次出现的位置为" << i << endl;
           return OK;
		}
			
		else
			p = p->next;
	}
	return ERROR;
}
Status  Find_Kth(int k, stu* list)//寻找第K个结点的值
{
	stu* p = list;
	p = p->next;
	int i = 1;
	while (p->next!=NULL && i < k)//p->next==NULL的时候说明此时p已经是最后一个结点
	{
        i++;
        p = p->next;
	}
	if (i == k)
	{ 
		cout << "第" << k << "个结点的值为" << p->score << endl;
		return OK;
	}
	else
	{
		cout << "没有第" << k << "个结点" << endl;
       return ERROR;
	}
		
}
Status Delete_k(int k, stu* list)//删除所有元素为K的结点
{
	stu* p = list;
	while (p->next)
	{
		if (p->next->score == k)
		{
			stu* q = new stu;
			q = p->next; 
			p->next = p->next->next;
			p->next->last = p;
			delete q;
		}
		else
		p = p->next;
	}
return OK;
}
Status Clear_link(stu* head)
{
	if (head == NULL)
	{
		return ERROR;
	}
	stu* p = head;
	p = p->next;
	while (p != NULL)
	{
		stu* tmp = p;
		p = p->next;
		free(tmp);
	}
	head->next = NULL;
	cout << "链表已清空" << endl;
	return OK;
} 
int main()
{
	stu* L;
	Initlist(L);
	Insert(1, 3, L);
	Insert(1, 3, L);
	Insert(1, 3, L);
	Insert(2, 8, L);
	Insert(1, 3, L);
	Insert(1, 2, L);
	Insert(Get_length(L)+1, 2, L);
	Print_link(L);
	Delete_k(3, L);
	Print_link(L);
	return 0;
}
//嗨害嗨

双向循环链表

#include<stdlib.h>
#include<stdbool.h>
#include<iostream>
using namespace std;
struct student
{
	int score;
	struct student* next;
	struct student* last;
};
typedef struct student stu;
void Initlist(stu*& L)//初始化 stu* &L表示对一个指针的引用
{
	L = new stu;
	L->next = L;
	L->last = L;
}

stu* Creat_Node(int x)//申请结点
{
	stu* new_node = new stu;
	new_node->score = x;
	new_node->next = NULL;
	new_node->last = NULL;
	return new_node;
}

void Print(stu* head)//打印
{
	if (head->next == head)
	{
		cout << "空表" << endl;
		return;
	}
	stu* current = head->next;
	while (current != head)
	{
		cout << current->score << endl;
		current = current->next;
	}
}

void Tail_Plug(stu* head, int x)//尾插
{
	stu* new_node = Creat_Node(x);
	new_node->next = head;
	new_node->last = head->last;
	head->last->next = new_node;
	head->last = new_node;
}

void Delete_tail(stu* head)//尾删
{
	stu* p = head->last;
	p->last->next = head;
	head->last = p->last;
	delete p;
}

void Head_Plug(stu* head, int x)//头插
{
	stu* p = Creat_Node(x);
	p->next = head->next;
	head->next->last = p;
	p->last = head;
	head->next = p;
}

void Delete_head(stu* head)//头删
{
	stu* p = head->next;
	head->next = p->next;
	p->next->last = head;
	delete p;
}

int Get_length(stu* head)//获得链表长度
{
	stu* p = head;
	if (p->next == NULL)
	{
		return 0;
	}
	int j = 0;
	while (p->next != head)
	{
		p = p->next;
		j++;
	}
	return j;
}

void Insert(int i, int k, stu* L)//在第i个位置插入k;
{
	if (i <= Get_length(L))
	{
		stu* o = L;
		for (int j = 1; j < i; j++)
		{
			o = o->next;
		}
		stu* p = Creat_Node(k);
		p->next = o->next;
		p->last = o;
		o->next = p;
	}
	else
		cout << "第" << i << "个位置不合法" << endl;
}

void Delete_Kth(stu* list, int k)//删除第k个结点
{
	if (k > Get_length(list) || k < 1)
	{
		cout << "没有第" << k << "个结点" << endl;
		return;
	}
	for (int i = 1; i < k; i++)
	{
		list = list->next;
	}
	stu* p = list->next;
	list->next = list->next->next;
	list->next->last = list;
	delete p;
}

void Find_first(int k, stu* list)//寻找出现值的第一个结点
{
	stu* p = list;
	p = p->next;
	for (int i = 1; i <= Get_length(list); i++)
	{
		if (p->score == k)
		{
			cout << k << "第一次出现的位置为" << i << endl;
			return;
		}
		else
			p = p->next;
	}
	cout << "表中没有值为" << k << "的结点" << endl;
}

void Find_Kth(int k, stu* head)//寻找第K个结点的值
{
	int i = k;
	if (k <= Get_length(head))
	{
		stu* p = head;
		while (i--)
		{
			p = p->next;
		}
		cout << "第" << k << "个结点的值为" << p->score << endl;
		return;
	}
	else
	{
		cout << "没有第" << k << "个结点" << endl;
		return;
	}
}

void Delete_k(int k, stu* list)//删除所有元素为K的结点
{
	stu* p = list;
	while (p->next != list)
	{
		if (p->next->score == k)
		{
			stu* q = new stu;
			q = p->next;
			p->next = p->next->next;
			p->next->last = p;
			delete q;
		}
		else
			p = p->next;
	}
}

void Clear_link(stu* head)//清空链表
{
	int k = Get_length(head);
	for (int i = 1; i <= k; i++)
	{
		Delete_Kth(head, 1);
	}
	cout << "链表已清空" << endl;
}

int main()
{
	stu* L;
	Initlist(L);
	Tail_Plug(L, 1);
	Tail_Plug(L, 2);
	Tail_Plug(L, 3);
	Tail_Plug(L, 4);
	Head_Plug(L, 8);
	Insert(2, 8, L);
	Insert(2, 8, L);
	Insert(2, 8, L);
	Insert(2, 8, L);
	Insert(108, 5, L);
	Print(L);
	Clear_link(L);
	Print(L);
	return 0;
}
//嗨害嗨

有何不足欢迎批评指正

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值