王道书籍上单链表的基本操作和课后部分习题
一:头文件的定义
#ifndef LINKLIST_H
#define LINKLIST_H
/**
* @author Dawn
* @date 2019年11月7日19:57:24
* @version 1.0
* 数据结构二轮复习之顺序表,不要问我为什么时间不对劲,电脑的机械硬盘坏了,晕,所有东西都没了,现在都在重写
*/
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
typedef int ElemType;
typedef struct LNode {
ElemType data;//数据域
struct LNode* next;
}LNode, * LinkList;
//循环双链表,仅仅是为了17题写的,没有初始化,懒得写那些了,运行不出来的!!
typedef struct DSNode {
ElemType data;
struct DSNode* next;
struct DSNode* prior;
}DSNode,*DSLinkList;
//==========================单链表的基本操作==============================
//1.头插法建立单链表(带头结点,没有特殊说明默认是带头节点的)
LinkList List_Insert_Head(LinkList& L);
LinkList List_Insert_NoHead(LinkList& L);//(不带头节点的)
//2.尾插法建立单链表
LinkList List_Insert_Tail(LinkList& L);
//3.按序号查找节点
LNode *GetElem(LinkList L, int i);
//4.按值查找节点
LNode* LocateElem(LinkList L, ElemType e);
//==========================课后习题======================================
//1.使用递归,删除不带头节点的单链表L中所有值为x的节点
void Del_X1(LinkList& L, ElemType e);
//2.在带头节点的单链表L中,删除L中所有值为x的节点
void Del_X2(LinkList& L, ElemType e);
//3.从尾到头输出带头结点的单链表L中的所有节点值;
void R_Print3(LinkList L);
//4.删除带头结点的单链表L中最小值的节点高效方法(该最小值节点唯一)
void Del_Min4(LinkList& L);
//5.带头结点的单链表逆置
void Reverse5(LinkList& L);
//6.使带头节点的单链表有序
void Sort_LinkList6(LinkList& L);
//7.删除无序带头节点的单链表L中值在(min,max)之间的节点
void Del_range(LinkList& L, int min, int max);
//8.给2个单链表,找出2个单链表的公共节点
LNode* Find_SameNode(LinkList A, LinkList B);
//9.给定一个带头节点的单链表,递增输出各个节点的值,并释放节点空间
//思路?先找到单链表中元素最小的值,然后就删除该节点
void Del_Mins(LinkList& L);
//10.将单链表A分为2个单链表A,B。A中存原表中序号为奇数的节点,B中存原表中序号为偶数的节点。且保持相对位置不变
LinkList Split2LinkList10(LinkList& A);
//11.将单链表A{a1,b1,a2,b2,a3,b3}分解为A{a1,a2,a3} B{b3,b2,b1}。此题和上一题要求差不多只不过B中元素逆置了.这里B中就用头插法来实现,A中还是用尾插法完成
LinkList Split2LinkList11(LinkList& A);
//12.在有序的单链表中,删除值相同的节点(记得保留一个),
void Del_Same(LinkList& L);
//13.将2个有序递增的单链表AB合并成一个有序递减的单链表A
void MergeList(LinkList& A, LinkList& B);
//14.将2个有序单链表中的公共值节点拼成一个新的链表C。不要删除原来节点的值
LinkList Get_Common(LinkList A, LinkList B);
//15.求2个有序链表的并集,
LinkList Union(LinkList& la, LinkList& lb);
//16.判断一个链表是否是另一个链表的子链表,也就是字符串判断他的子串 好像是Java中的Contains函数??唉!!为了复习考研我竟然有大半年没有写Java了。
bool Pattern(LinkList A, LinkList B);
//17.判断一个循环双链表是否对称
bool Symmetry(DSLinkList L);
//18.将2个循环单链表合并成一个循环单链表,保持相对位置不变
LinkList Link(LinkList& h1, LinkList& h2);
//19.依次输出循环单链表中的较小值。并删除最小值节点
void Del_MinAll(LinkList& L);
//==========================广大915真题篇==============================
//2019第二题,要求:将一个带头节点的单链表L中值重复的多余节点删除,(就是去重)
void DelDistincts(LinkList& L);
//==========================常用函数==============================
void PrintList(LinkList L);
void PrintList_NoHead(LinkList L);
#endif // !LINKLIST_H
二:头文件具体的实现
#include"LinkList.h"
//==========================单链表的基本操作==============================
//1.头插法建立单链表(带头结点,没有特殊说明默认是带头节点的)
LinkList List_Insert_Head(LinkList& L) {
int arr[6] = { 1,2,3,4,5,6 };//将改数组插入到单链表中
LNode* s;//待插入的节点
int i = 0;
L = (LinkList)malloc(sizeof(LNode));//创建头节点
L->next = NULL;
while (i < 6) {
s = (LNode*)malloc(sizeof(LNode));
s->data = arr[i++];
s->next = L->next;//将L后的东西放在S后面,以避免丢失
L->next = s;
}
return L;
}
//(不带头节点的)
LinkList List_Insert_NoHead(LinkList& L) {
int arr[6] = { 1,2,3,4,5,6 };//将改数组插入到单链表中
LNode* s;//待插入的节点
int i = 0;
while (i < 6) {
if (i == 0) {
L = (LinkList)malloc(sizeof(LNode));
L->data = arr[i++];
L->next = NULL;
}
else {
s = (LNode*)malloc(sizeof(LNode));
s->data = arr[i++];
//s->next = L->next; //这样写出来的是1 6 5 4 3 2
//L->next = s;
s->next = L;
L = s;
}
}
return L;
}
//2.尾插法建立单链表
LinkList List_Insert_Tail(LinkList& L) {
//int arr[6] = { 1,2,3,4,5,6 };//将改数组插入到单链表中
int arr[6] = { 1,2,2,4,5,6 };//将改数组插入到单链表中
L = (LinkList)malloc(sizeof(LNode));//创建头节点
LNode* s, * r = L;//s为待插入的节点,r指向尾指针的
int i = 0;
while (i < 6) {
s = (LNode*)malloc(sizeof(LNode));
s->data = arr[i++];
r->next = s;
r = s;
}
r->next = NULL;//最后尾指针指向NULL
return L;
}
//3.按序号查找节点
//如果输入的是0,就返回头节点,小于1退出,
LNode* GetElem(LinkList L, int i) {
int j=1;//从1开始计数
LNode* p = L->next;//p为工作指针
if (i == 0)
return L;//返回头节点
if (i < 1)
return NULL;
while (p && j < i) {
p = p->next;
j++;
}
return p;//注意这里p,因为循环里面写的p=p->next
}
//4.按值查找节点
LNode* LocateElem(LinkList L, ElemType e) {
LNode* p = L->next;
while (p != NULL && p->data != e) {
p = p->next;
}
return p;
}
//==========================课后习题======================================
//1.使用递归,删除不带头节点的单链表L中所有值为x的节点
//递归条件:当改节点值是x就删除在递归调用该函数,不是该节点就调用该节点的的next。
//递归退出条件:递归到最后一个节点就没了
void Del_X1(LinkList &L, ElemType e) {
LNode* q;//待删除的节点
if (L == NULL)
return;
if (L->data == e) {
q = L;
L = L->next;
free(q);//释放该节点
Del_X1(L, e);
}
else {
Del_X1(L->next, e);
}
}
//2.在带头节点的单链表L中,删除L中所有值为x的节点
void Del_X2(LinkList& L, ElemType e) {
LNode *p = L->next;//p工作指针
LNode* prep = L;//p的前驱
LNode* q;//待删除的节点
while (p) {
//如果p是要删除的值
if (p->data == e) {
q = p;
p=p->next;
prep->next = p;//不写这一句就要断链了
free(q);
}
else {
prep = p;
p = p->next;
}
}
}
//3.从尾到头输出带头结点的单链表L中的所有节点值;
void R_Print3(LinkList L) {
//使用递归
//if (L) {
// R_Print3(L->next);
//}
//if(L)
// printf("%d ,", L->data);
if (L->next!=NULL) {
R_Print3(L->next);
}
printf("%d ,", L->data);
}
//4.删除带头结点的单链表L中最小值的节点高效方法(该最小值节点唯一)
void Del_Min4(LinkList& L) {
//这个不是有序的,我还打算用二分法找最下值元素了,可以吗?? 哦哦,也不可以哈,顺序存储才得行哈!!发散思维到此结束
LNode* p = L->next, *prep = L;//p prep视为工作指针
LNode* minp = p, * prepmin = prep;//分别保存最下值的节点以及他的前驱
while (p) {
if (p->data < minp->data) {
//p小于minp
minp = p;
prepmin = prep;
}
prep = p;
p = p->next;
}
//找到了最小值的节点以及他的前驱
prepmin->next = minp->next;
free(minp);
}
//5.带头结点的单链表逆置
void Reverse5(LinkList& L) {
//使用头插法的方法就行了
LNode* p = L->next, * r;//p为工作指针, r为插入之后的尾指针
L->next = NULL;//这里就将L->next置空
while (p != NULL) {
r = p->next;
p->next = L->next;
L->next = p;
p = r;
}
}
//6.使带头节点的单链表有序(有点陌生,许多看)
//使用了直接插入排序的思想,1:pre为有序部分的单链表遍历时的工作指针,遍历完一遍之后的结果是指向第一个大于待插入节点值的前驱元素,
// 2:找到合适的pre之后,就插入p(无序部分的工作指针)的值,插入成功之后p后移,直到p遍历完成
void Sort_LinkList6(LinkList& L) {
LNode* p=L->next, * pre;//p为无序断的工作指针,pre找到插入的合适位置的前驱 的工作指针
LNode* r = p->next;//保证p不断链
p->next = NULL;
p = r;//执行第二个节点
while (p != NULL) {
r = p->next;
pre = L;
//pre的后继有元素,pre后继元素的值小于p的值,pre就向下移
while (pre->next != NULL && pre->next->data < p->data) {
pre = pre->next;
}
p->next = pre->next;
pre->next = p;
p = r;//扫描表中剩下的节点
}
}
//7.删除无序带头节点的单链表L中值在(min,max)之间的节点
void Del_range(LinkList& L, int min, int max) {
//通过2个指针来实现
LNode* p = L->next, * pre = L;//p为工作指针,pre为它的前驱
LNode* q;//待删除的节点
while (p != NULL) {
if (p->data > min&& p->data < max) {
q = p;
p = p->next;
pre->next = p;//防止断链
free(q);//删除
}
else {
pre = p;
p = p->next;
}
}
}
//8.给2个单链表,找出2个单链表的公共节点,就像一个躺着的Y
//思路:先找到比较长的单链表,从左向右遍历,遍历到和短的单链表长度一样适合,在同时遍历2个单链表,每次遍历的时候就比较地址
/* 0x0001 ->next 0x0004 ->next
地址表示: ———— 0x0008 ->next 0x0012 ->next 0x0000
/
0x0002 ->next 0x0003 ->next 0x0005 ->next
*/
LNode* Find_SameNode(LinkList A, LinkList B) {
//这里就直接赋值A B的长度了,没有写length(A)函数,
int Alen = 4, Blen = 5;//这里按照上面图来赋值的
LinkList longList, shortList;//分别指向较长的单链表和较短的单链表
int dist;//2个链表长度差
if (Alen > Blen) {
longList = A->next;
shortList = B->next;
dist = longList - shortList;
}
else {
longList = B->next;
shortList = A->next;
dist = longList - shortList;
}
while (dist--)
longList = longList->next;//后移dist(AB长度差),使之同步
//开始寻找公共节点
while (longList != NULL) {
if (longList == shortList)//比较的是地址
return longList;//返回二者之一均可
else {
longList = longList->next;
shortList = shortList->next;
}//if结束
}
return NULL;
}
//9.给定一个带头节点的单链表,递增输出各个节点的值,并释放节点空间
//思路?先找到单链表中元素最小的值,然后就删除该节点。(这里注意的是在找最小值节点的时候,每次都是从第一个节点开始找)
void Del_Mins(LinkList& L) {
LNode* p,* pre, * q;//p工作指针,pre为待删除节点的前驱,q为待删除的节点
while (L->next != NULL) {
//每次都会少一个最小值的节点
pre = L;
p = pre->next;//每次都从第二个元素开始寻找,第一个元素都使pre->next(也就是最小值的元素)
while (p->next!=NULL) {//(助记:每次最开始的一次循环是:第二个元素和第一个元素比较大小)
if (p->next->data < pre->next->data) {
pre = p;//将最小值的前驱节点更新
}
p = p->next;
}
//通过这个循环找到了最小值节点的前驱
q = pre->next;
printf("%d, ", q->data);
pre->next = q->next;//删除了该节点
free(q);
}
//最后释放头节点
free(L);
}
//10.将单链表A分为2个单链表A,B。A中存原表中序号为奇数的节点,B中存原表中序号为偶数的节点。且保持相对位置不变
LinkList Split2LinkList10(LinkList& A) {
int i = 0;//用来判断是奇数还是偶数位序的节点
//创建B链表
LinkList B = (LinkList)malloc(sizeof(LNode));
B->next = NULL;
LNode* ra = A, * rb = B;//ra,rb分别是AB的尾节点,因为要保持先对位置不变,就使用尾插法
LNode* p = A->next;//p为工作指针
A->next = NULL;//A链表置空,以便插入。不要误以为A链表之后的东西就没了,其实p一直保存起来的了
while (p != NULL) {
i++;
if (i % 2 == 0) {//偶数插入B中
rb->next = p;
rb = p;
}
else {
ra->next = p;
ra = p;
}
p = p->next;
}
//插入成功,再将A B 2链表的尾节点置空
ra->next = NULL;
rb->next = NULL;
return B;
}
//11.将单链表A{a1,b1,a2,b2,a3,b3}分解为A{a1,a2,a3} B{b3,b2,b1}。此题和上一题要求差不多只不过B中元素逆置了.这里B中就用头插法来实现,A中还是用尾插法完成
LinkList Split2LinkList11(LinkList& A) {
LinkList B = (LinkList)malloc(sizeof(LNode));
B->next = NULL;
LNode* p = A->next, * q;//p为工作指针 。当p节点插入到B中的时候,就用q来防止断链的
LNode* ra = A;//为A的尾节点
while (p != NULL) {
ra->next = p;
ra = p;//A进行尾插法
p = p->next;
q = p->next;//即将插到B中,防止断链
p->next = B->next;
B->next = p;
p = q;//p插入成功之后,又接回到直接断链的位置
}
//循环结束,A链表尾指针置NULL
ra->next = NULL;
return B;
}
//12.在有序的单链表中,删除值相同的节点(记得保留一个),
void Del_Same(LinkList& L) {
LNode* p = L->next, * q;//q为要删除的重复节点
if (p == NULL)
return;
while (p->next != NULL) {
q = p->next;//同时q也是p的后继
if (p->data == q->data) {
p->next = q->next;
free(q);
}
else {
p = p->next;
}
}
}
//13.将2个有序递增的单链表AB合并成一个有序递减的单链表A
void MergeList(LinkList &A, LinkList &B) {
LNode* pa = A->next, * pb = B->next;//分别是AB的工作指针
LNode* r;//防止断链的
A->next = NULL;//将A置空,以便插入元素到里面
while (pa && pb) {//当2链表均不为空时候,循环
if (pa->data <= pb->data) {//如果pa的元素小于pb,就将pa使用头插法插到A中
r = pa->next;//防止断链
pa->next = A->next;
A->next = pa;
pa = r;//恢复pa的工作指针性质
}
else {
r = pb->next;
pb->next = A->next;
A->next = pb;
pb = r;
}
}
//通常情况下有一个链表会有剩余,
if (pa)
pb = pa;//如果pa不为空,pb就执行pa,(默认将pb认为指向不为空的那个链表)
while (pb) {
r = pb->next;
pb->next = A->next;
A->next = pb;
pb = r;
}
free(B);
}
//14.将2个有序单链表中的公共值节点拼成一个新的链表C。不要删除原来节点的值
//思路?step1:2个链表是有序的,可以从第一个元素一次比较A B2表中的元素。
// step2:如果元素值不相等,则值小的指针后移。
// step3:如果元素相等,创建一个值等于2节点的新节点,再使用尾插法插入的C中,最后2工作指针都后移一位
LinkList Get_Common(LinkList A, LinkList B) {
LNode* p = A->next, * q = B->next;//p q分别为A.B的工作指针
LNode* r;//为C的尾节点,进行尾插法使用的
LNode* s;//为值相同的新节点
LinkList C = (LinkList)malloc(sizeof(LNode));
r = C;
while (p != NULL && q != NULL) {
if (p->data < q->data) {
p = p->next;
}
else if (p->data > q->data) {
q = q->next;
}
else {
s = (LNode*)malloc(sizeof(LNode));
//将值相同的节点复制到s的数据域中
s->data = p->data;
r->next = s;
r = s;
//p q同时后移
p = p->next;
q = q->next;
}
}
r->next = NULL;
return C;
}
//15.求2个有序链表的并集,
//思路:1:使用归并的方法,设置2个工作指针pa,pb,对2个链表进行归并并扫描,
// 2:只有同时出现在2个集合中的元素链接到结果表中,且仅保留一个其他节点全部释放掉,
// 3:当其中一个节点遍历完之后,释放另一个剩下表的全部节点
LinkList Union(LinkList& la, LinkList& lb) {
LNode* pa = la->next;
LNode* pb = lb->next;//工作指针pa pb
LNode* u;//待删除的节点
LNode* pc = la;//结果表中当前合并节点的前驱指针(这里的结果表示la哦。不要搞错了)
while (pa && pb) {
if (pa->data == pb->data) {
//交集放入到尾插到结果表中
pc->next = pa;
pc = pa;
pa = pa->next;
u = pb;//删除B中的相同节点
pb = pb->next;
free(u);
}
else if (pa->data < pb->data) {
u = pa;
pa = pa->next;
free(u);
}
else {
u = pb;
pb = pb->next;
free(u);
}
}
while (pa) {
u = pa;
pa = pa->next;
free(u);
}
while (pb) {
u = pb;
pb = pb->next;
free(u);
}
pc->next = NULL;//尾插法的嘛。记得尾节点指向NULL
free(lb);//记得删除lb,不是删除la,也不应该删除la,因为是把节点插入到la中的
return la;
}
//16.判断一个链表是否是另一个链表的子链表(没有头节点的),也就是字符串判断他的子串 好像是Java中的Contains函数??唉!!为了复习考研我竟然有大半年没有写Java了。
bool Pattern(LinkList A, LinkList B) {
LNode* p = A;
LNode* pre = p;//记录每趟比较链表中的开始节点
LNode* q = B;
while (p && q) {
if (p->data == q->data) {
p = p->next;
q = q->next;
}
else {
pre = pre->next;
p = pre;//p又为A链表中的新开始比较节点
q = B;//q从B链表第一个节点开始
}
}
if (q == NULL)
return true;//q为空说明B就是A的子序列
else
return false;
}
//17.判断一个循环双链表是否对称
bool Symmetry(DSLinkList L) {
DSNode* p = L->next, * q = L->prior;//p从左向右遍历,q从右向左遍历
while (p != q && p->next != q) {//当q p不等,或者p q相邻就退出循环
if (p->data == q->data) {
p = p->next;
q = q->prior;
}
else {
return false;//有一个不相同就是不对称的
}
}
return true;
}
//18.将2个循环单链表合并成一个循环单链表,保持相对位置不变
LinkList Link(LinkList& h1, LinkList& h2) {
//step1:找到2个循环单链表的尾节点
LNode* p, * q;
p = h1;
q = h2;
while (p->next != h1)
p = p->next;
while (q->next != h2)
q = q->next;
//step2:将h1的尾节点指向h2的头节点,h2的尾节点指向h1的头节点
p->next = h2;
q->next = h1;
return h1;
}
//19.依次输出循环单链表中的较小值。并删除最小值节点
void Del_MinAll(LinkList& L) {
LNode* p, * pre, * minp, * minpre;//p为工作指针,pre为它的前驱,minp指向最小值的节点,minpre为它的前驱
while (L->next = L) {//循环单练表的嘛
p = L->next;
pre = L;
minp = p;
minpre = pre;
//找最小值
while (p != L) {
if (p->data < minp->data) {
minp = p;
minpre = pre;
}
pre = p;
p = p->next;
}
printf("%d, ", minp->data);
minpre->next = minp->next;//删除该节点
free(minp);
}
free(L);//释放头节点
}
//==========================广大915真题篇==============================
//2019第二题,要求:将一个带头节点的单链表L中值重复的多余节点删除,(就是去重)
void DelDistincts(LinkList& L) {
LNode* p, * pre, * q;//p为工作指针,pre为它的前驱,q为待删除的节点
pre = L;
p = L->next;
while (p) {
if (p->data == pre->data) {
q = p;
p = p->next;
pre->next = p;
free(q);
}
else {
pre = p;
p = p->next;//如果pre和p不同,则同时后移
}
}
}
//==========================常用函数==============================
void PrintList(LinkList L) {
LNode* p = L->next;
while (p) {
printf("%d ,", p->data);
p = p->next;
}
printf("
");
}
void PrintList_NoHead(LinkList L) {
while (L) {
printf("%d ,", L->data);
L = L->next;
}
printf("
");
}
三:主函数如下
#include"LinkList.h"
int main() {
LinkList L;
LNode* temp;
//==========================单链表的基本操作==============================
//1.头插法
//List_Insert_Head(L);
//List_Insert_NoHead(L);
//2.尾插法
List_Insert_Tail(L);
//3.按序号查找节点
//temp =GetElem(L, 3);
//printf("%d
", temp->data);
//4.按值查找节点
//LocateElem(L, 3);
//==========================课后习题======================================
//1.使用递归,删除不带头节点的单链表L中所有值为x的节点(测试记得使用头插法不带头节点的函数)
//Del_X1(L, 3);
//2.在带头节点的单链表L中,删除L中所有值为x的节点
//Del_X2(L, 3);
//3.从尾到头输出带头结点的单链表L中的所有节点值;
//R_Print3(L);
//printf("
");
//4.删除带头结点的单链表L中最小值的节点高效方法(该最小值节点唯一)
//Del_Min4(L);
//5.带头结点的单链表逆置
//Reverse5(L);
//6.使带头节点的单链表有序
//Sort_LinkList6(L);
//7.删除无序带头节点的单链表L中值在(min,max)之间的节点
//Del_range(L,2 ,5);
//8.给2个单链表,找出2个单链表的公共节点,就像一个躺着的Y
//注意:怎么说了,这个单链表我又不能手动赋指定地址值,所以就实现不了。要想实现,就将找公共节点改为公共值的节点,节点值看成节点地址值。
//我也懒得写了,考试也考不到这里来,再过25分钟,距离考研只有43天了我线性代数都还没有复习完,我靠( ‵o′)凸。算了,洗漱早睡,明早看线性代数,
////Find_SameNode(L,L);不用打开,跑不起来的
//9.给定一个带头节点的单链表,递增输出各个节点的值,并释放节点空间
//思路?先找到单链表中元素最小的值,然后就删除该节点
//Del_Mins(L);
//10.将单链表A分为2个单链表A,B。A中存原表中序号为奇数的节点,B中存原表中序号为偶数的节点。且保持相对位置不变
//LinkList B = Split2LinkList10(L);//(L相当于A)
//printf("B链表输入如下:");
//PrintList(B);
//printf("A链表输入如下:");
//11.将单链表A{a1,b1,a2,b2,a3,b3}分解为A{a1,a2,a3} B{b3,b2,b1}。此题和上一题要求差不多只不过B中元素逆置了.这里B中就用头插法来实现,A中还是用尾插法完成
//LinkList B = Split2LinkList11( L);
//printf("B链表输入如下:");
//PrintList(B);
//printf("A链表输入如下:");
//12.在有序的单链表中,删除值相同的节点(记得保留一个)
//测试的时候,将头插法的那个数组改一下
//Del_Same(L);
//13.将2个有序递增的单链表AB合并成一个有序递减的单链表A
//LinkList B;
//List_Insert_Tail(B);
//MergeList(L,B);
//14.将2个有序单链表中的公共值节点拼成一个新的链表C。不要删除原来节点的值
//LinkList C = Get_Common(L,L);
//PrintList(C);
//15.求2个有序链表的并集,
//LinkList B;
//List_Insert_Tail(B);
//LinkList C = Union(L, B);
//PrintList(C);
//16.判断一个链表是否是另一个链表的子链表,也就是字符串判断他的子串 好像是Java中的Contains函数??唉!!为了复习考研我竟然有大半年没有写Java了。
//List_Insert_NoHead(L);
// printf("%s
", Pattern(L, L)?"是":"不是");
//17.判断一个循环双链表是否对称.不能测试,记住代码就行了
//// Symmetry(L);
//18.将2个循环单链表合并成一个循环单链表,保持相对位置不变. 不能测试,记住代码就行了
////Link(h1,h2)
//19.依次输出循环单链表中的较小值。并删除最小值节点
////Del_MinAll(L);
//后面的不写了,广大考不了那么难,我的高数都还复习完,时间宝贵
//PrintList(L);
//PrintList_NoHead(L);
//==========================广大915真题篇==============================
//2019第二题,要求:将一个带头节点的单链表L中值重复的多余节点删除,(就是去重)
DelDistincts(L);
PrintList(L);
return 0;
}