链表的八大操作

链表的八大操作,只额外列出创建操作,其他操作均在完整代码中

创建链表–二级指针法,一级指针就带个返回参数即可

void create(Pst *List) // 1.创建链表
{
    (*List) = (Pst)malloc(sizeof(st)); // 堆区中申请内存空间
    (*List)->data = 1;                 // 初始化
    (*List)->next = NULL;
}

创建链表–一级指针法

Pst create2(Pst List)
{
	List = (Pst)malloc(sizeof(st));
	List->data = 0;
	List->next = NULL;
	return List;
}

删除链表

void delet_destory(Pst *List) // 9.破坏链表(二级指针,头结点无需二次free,一步解决)
{
	Pst p;
	// 记录(*List)位置

	while (p != NULL) // 参数校验
	{
		p = (*List)->next;
		// 移动指针位置
		free((*List)); // 释放内存
		(*List) = p;   // 记录此时(*List)位置
	}
	puts("SCESSE");
}

完整代码

#include <stdio.h>
#include <stdlib.h>
typedef struct Node
{
	int data;
	struct Node *next;
} st, *Pst;
Pst createNode(int data) // 创建节点
{
	Pst newNode = (Pst)malloc(sizeof(st)); // 申请空间
	newNode->data = data;				   // 初始化
	newNode->next = NULL;
	return newNode;
}
void create(Pst *List) // 1.创建链表
{
	(*List) = (Pst)malloc(sizeof(st)); // 堆区中申请内存空间
	(*List)->data = 1;				   // 初始化
	(*List)->next = NULL;
}
Pst create2(Pst List)
{
	List = (Pst)malloc(sizeof(st));
	List->data = 0;
	List->next = NULL;
	return List;
}
int return_length(Pst List) // 2.返回表长
{
	int i = 0;
	Pst replace = List;
	while (replace != NULL) // 遍历列表
	{
		i++;
		replace = replace->next; // 依次往后移
	}
	return i;
}
void insert(Pst List, int data, int pos) // 3.插入链表
{
	int i;
	Pst newNode = createNode(data); // 创建新节点方便后续插入
	if (pos < 0)					// 参数校验,pos<0时,退出函数
		exit(0);
	else if (pos > return_length(List))
	{
		pos = 0;
	}
	for (i = 0; i < pos; i++) // 移动指针到指定位置,进行后续的插入操作
	{
		List = List->next;
	}
	newNode->next = List->next; // 插入指定位置后
	List->next = newNode;
}
Pst search(Pst List, int value) //  4.查询链表
{
	if (List == NULL)
	{
		return List;
	}
	while (List->next != NULL) // 找到对应value所在节点
	{
		if (List->data == value) // 找到对应项,返回所在节点
		{
			return List;
		}
		List = List->next;
	}
	return List; // 返回当前所在节点,链表已经走到结尾,返回输出时为NULL
}
void print_List(Pst List) // 5.输出链表
{
	Pst pMove; // 定义一个移动指针变量
	if (List == NULL)
	{
		puts("链表已毁");
		exit(0);
	}
	pMove = List->next; // 排除初始化的头指针
	while (pMove != NULL)
	{
		printf("%d ", pMove->data);
		pMove = pMove->next; // 依次往后挪
	}
}
int merge(Pst p1, Pst p2) // 6.合并链表
{
	Pst r;
	create(&r);
	r = p2;
	while (p1->next != NULL) // 将列表结点移动到NULL前
	{
		p1 = p1->next;
	}
	p1->next = r->next; // 将p2的头结点连接到p1的尾节点
	return 0;
}
int delet_List(Pst List, int number) // 7.删除链表节点
{
	int flag = 0;
	Pst other;
	Pst posfront = List, pos = List->next; // 定义左指针和右指针的指针变量
	while (pos != NULL)					   // 右指针指向当前位置,左指针指向当前位置的前一个位置
	{
		if (number == pos->data) // 找到数据
		{
			other = pos;
			posfront->next = pos->next; // 删除节点
			flag = 1;
			free(other);
			break;
		}
		else
		{
			posfront = pos; // 一次两个指针移动一位
			pos = pos->next;
		}
	}
	if (flag == 0) // 为找到相应值对应的节点,删除失败
	{
		return -1;
	}
	return 0;
}
Pst reverse_List(Pst List) // 8.单链颠倒
{
	Pst pos, p, q;	  // 定义两个结构体指针变量
	pos = List->next; // 左指针指向头结点
	p = q = NULL;
	while (pos != NULL)
	{
		q = pos->next; // 右指针指向当前位置的下一个
		pos->next = p; // 现将pos位置的节点反向指到P(第一次P为NULL)
		p = pos;	   // POS未改变时,记下pos节点所在位置,以便后续反向
		pos = q;	   // 将pos指针往下移动
	}
	return p;
}

void delet_destory(Pst *List) // 9.破坏链表(二级指针,头结点无需二次free,一步解决)
{
	Pst p;
	// 记录(*List)位置

	while (p != NULL) // 参数校验
	{
		p = (*List)->next;
		// 移动指针位置
		free((*List)); // 释放内存
		(*List) = p;   // 记录此时(*List)位置
	}
	puts("SCCESSE");
}

void devideList(Pst List1, Pst List2) // 10.拆分链表
{
	int i, j, cnt = 0;
	i = return_length(List1);
	j = return_length(List2);
	while (cnt < i - j) // 找到合并位置,最后拆分。
	{
		List1 = List1->next;
		cnt++;
	}
	List1->next = NULL;
}
int main()
{
	Pst List, List2, List3;
	int data, n, ret;
	Pst List_reverse;
	create(&List); // 创建链表
	create(&List_reverse);
	create(&List2);
	List3 = create2(List3);
	puts("1:continue,0:exits");
	puts("input to the choice");
	scanf("%d", &n);
	insert(List, 33, 0);  // 插入初始对象。
	insert(List, 20, 0);  // 插入初始对象。
	insert(List, 15, 0);  // 插入初始对象。
	insert(List2, 22, 0); // 插入初始对象。
	while (n != 0)		  // 向链表中输入
	{
		puts("请输入你想插入的值"); //
		scanf("%d", &data);
		insert(List, data, 50);
		puts("1:继续插入,,0:停止插入");
		scanf("%d", &n);
	}
	puts("List插入后 ");
	print_List(List);
	puts("");
	puts("List1 合并后");
	merge(List, List2); // 合并Lists和List2
	print_List(List);
	print_List(List2);
	puts("");
	ret = delet_List(List, 20); // 凭值删链
	puts("删除 20后");
	print_List(List);
	puts("");
	puts("单链表颠倒后");
	List_reverse->next = reverse_List(List); // 逆序链表
	print_List(List_reverse);
	List->next = reverse_List(List_reverse); // 返回原值。
	puts("");
	puts("15为头结点开始的链(原来的链,方便后续看15节点开始那条链)");
	List->next = search(List, 15); // 获取15开始的那条链
	print_List(List);
	puts("\n摧毁链表2后");
	devideList(List, List2); // 得先拆分链表,因为原List1的尾指向p2,如果不拆开,破坏链表时会造成后续值二次释放报错。
	delet_destory(&List2);
	print_List(List2);
	puts("\n摧毁链表1后");
	delet_destory(&List); // 摧毁链表
	print_List(List);	  // 检验链表是否破坏成功
	return 0;
}
C语言中的链表(如单向链表)和顺序表(数组实现的线性表)虽然在结构上有所不同,但它们的一些基本操作大体相似,包括创建、插入、删除、查找、遍历等。以下是C语言中这两种数据结构常见的八种操作的简要代码示例: **一、顺序表的操作:** 1. **创建列表(初始化)**: ```c int seq_list[10]; // 创建一个大小为10的顺序表 ``` 2. **插入元素**: ```c void insert_seq(int index, int value, int *seq) { if (index < 0 || index > sizeof(seq)/sizeof(seq[0])) return; memmove(&seq[index+1], &seq[index], sizeof(seq)/sizeof(seq[0]) - index); seq[index] = value; } ``` 3. **删除元素**: ```c void delete_seq(int index, int *seq) { if (index >= 0 && index < sizeof(seq)/sizeof(seq[0])) { memmove(&seq[index], &seq[index+1], sizeof(seq)/sizeof(seq[0]) - index); } } ``` 4. **查找元素**: ```c int search_seq(int value, const int *seq) { for (int i = 0; i < sizeof(seq)/sizeof(seq[0]); i++) { if (seq[i] == value) return i; } return -1; } ``` **二、链表操作:** 1. **创建链表**: ```c typedef struct ListNode { int data; struct ListNode* next; } ListNode; ListNode* create_linked_list() { ListNode* head = NULL; return head; } ``` 2. **插入节点**: ```c void insert_node(ListNode** head, int value) { ListNode* newNode = (ListNode*)malloc(sizeof(ListNode)); newNode->data = value; newNode->next = *head; *head = newNode; } ``` 3. **删除节点**: ```c void delete_node(ListNode** head, int value) { ListNode* temp = *head; if (temp != NULL && temp->data == value) { *head = temp->next; free(temp); } else { while (temp != NULL && temp->data != value) { temp = temp->next; } if (temp == NULL) return; ListNode* nextTemp = temp->next; free(temp); temp = nextTemp; } } ``` 4. **查找节点**: ```c ListNode* search_node(ListNode* head, int value) { while (head != NULL) { if (head->data == value) return head; head = head->next; } return NULL; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值