链表最全的相关知识及源码(包括如何创建结点、建立一个空链表、插入、删除、清空、求长度等等)
均采用函数封装形式给出,望各位大佬批评指正:
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
typedef int Element;
typedef struct node { //结点结构体定义
Element data;
struct node* next;
}ListNode;
typedef ListNode* LinkList; //链表指针定义
void InsertLinkList(LinkList& first, int x, int i) { //不带头结点的链表,在链表第i个节点处前插入新元素x
ListNode* p = first;
int k = 0;
while (p != NULL && k < i - 1) { //找到第i-1个结点
p = p->next;
k++;
}
if (p == NULL && first != NULL) { //位置无效
printf("无效的插入位置!\n");
}
ListNode* newnode = (ListNode*)malloc(sizeof(ListNode)); //建立新结点
newnode->data = x; //完成赋值
if (first == NULL || i == 1) { //插入空表或非空表第一个结点之前
newnode->next = first;
first = newnode;
}
else { //在中间插入
newnode->next = p->next;
p->next = newnode;
}
}
int DeleteLinkList(LinkList& first, int i) { //不带头结点的链表,删除第i个结点
ListNode* p, * q;
if (i == 0) { //默认第1个结点是首元结点,头结点不算一个结点
q = first;
first = first->next;
}
else {
p = first;
int k = 0;
while (p != NULL && k < i - 1) { //先找到第i-1个结点
p = p->next;
k++;
return 0;
}
if (p == NULL || p->next == NULL) { //没有找到结点
printf("无效位置\n");
exit(1);
}
else { //改变链表路径
q = p->next;
p->next = q->next;
}
}
int k = q->data; //设置k为一个存储器,保存被删掉结点的数据
free(q); //释放被删掉的结点
return k; //返回被删掉结点的值
}
int insertl(LinkList first, Element x, int i) { //带头结点的链表插入元素1
int k = 0;
ListNode* p = first;
while (k < i-1) { //找寻第i-1个结点
p = p->next;
}
if (p == NULL) { //无效位置
printf("输入的位置无效!\n");
return 0;
}
ListNode* newnode = (ListNode*)malloc(sizeof(ListNode)); //建立新结点
newnode->data = x; //为新结点赋值
newnode->next = p->next; //插入新结点
p->next = newnode;
return 1;
}
int deletel (LinkList first, int i) { //删除带头结点的链表
ListNode* q, * p = first;
int k = 0;
while (k < i-1) { //找到第i-1个结点
p = p->next;
}
if (p == NULL || p->next == NULL) { //无效位置进行退出并返回0
printf("输入的位置无效!\n");
return 0;
exit(1);
}
q = p->next; //删除目标结点
p->next = q->next;
free(q); //释放目标结点
return 1;
}
int LengthLinkList(LinkList first) { //求线性链表的长度
ListNode* p;
p = first->next; //从首元结点处开始计数
int count = 0;
while (p == NULL) {
p = p->next;
count++;
}
return count;
}
void MakeEmpty(LinkList first) { //删去链表中除表头结点外的所有其他结点
ListNode* q;
while (first->next != NULL) { //当链不空时,循环逐个删去所有结点
q = first->next;
first->next = q->next;
free(q);
}
}
ListNode* FindLinkList(LinkList first, Element value) { //按值查找
ListNode* p;
p = first->next; //指向首元结点
while (p != NULL && p->data != value) {
p = p->next;
}
if (p->data == value) return p;
else {
printf("woc,没找到!\n");
exit(1);
}
}
ListNode* Locate(LinkList first, int i) { //返回表中第i个元素的地址1(带头结点)
ListNode* p;
int k = 0;
if (i < 0) {
printf("输入的位置无效!\n");
exit(1);
}
p = first;
while (k < i) {
p = p->next;
k++;
}
if (k = i) return p;
else return NULL;
}
void CreateLinkList(LinkList* first, int n) { //创建链表,类似于尾插
int i;
(*first) = (LinkList)malloc(sizeof(ListNode)); //建立头结点
ListNode* p = *first;
for (i = 0; i < n; i++) {
ListNode* q = (ListNode*)malloc(sizeof(ListNode)); //动态内存分配
scanf("%d", &q->data);
p->next = q; //尾插法建立新链表
p = q;
}
p->next = NULL;
}
//设计一个算法,在带头结点的单链表L中删除所有值为x的结点并释放空结点 注:x不唯一
void del(LinkList* first,int x) {
ListNode* p = (*first)->next;
ListNode* pre = *first;
while (p != NULL) {
if (p->data == x) {
ListNode* q = p->next;
pre->next = q->next;
free(q);
}
else {
pre = p;
p = p->next;
}
}
}
//设计一个算法,在带头结点的单链表L中删除一个最小值结点,假设其唯一
void MinDel(LinkList* first) {
ListNode* minp = (*first)->next, * minpre = (*first);
ListNode* pre = *first,* p = minp;
while (p != NULL) {
if (p->data < minp->data) {
minp = p;
minpre = pre;
}
pre = p;
p = p->next;
}
minpre->next = minp->next;
free(minp);
}
//设计一个算法,将线性链表a,分解成为b和c 注:a的结构为{b1,c1,b2,c2,b3,c3.....}
void split(LinkList* a, LinkList* b, LinkList* c) {
ListNode* p = (*a)->next;
b = a;
(*c) = (ListNode*)malloc(sizeof(ListNode));
if (b == NULL || c == NULL) {
printf("拆分算法分配头结点失败,自动退出!\n");
exit(1);
}
ListNode* q = (*c), * pre = (*a);
while (p != NULL) {
p = p->next;
if (p != NULL) {
q->next = p;
q = p;
}
}
}
void PrintfLinkList(LinkList* first) { //输出新链表
ListNode* q = (*first)->next;
if ((*first)->next == NULL) {
printf("注意,此链表为空!\n");
}
while (q != NULL) {
printf("%d\n", q->data);
q = q->next;
}
}
我会一直保持更新的,
如果对大家有所帮助的话,可以评论、点赞、收藏和转发哦!