版权声明:谢谢 https://blog.csdn.net/Waybyway/article/details/83449668
一:LinkList.cpp文件
#include <stdio.h>
#include <malloc.h> //malloc函数 用了<stdlib.h>中的 <malloc.h>头文件
typedef int ElemType; //自定义类型 使 ElemType 为 int型
typedef struct LNode //定义单链表结点类型
{
ElemType data;
struct LNode *next; //定义链表结点类型的指针 指向后继结点
} LinkList;
/* 链表中 不同对指针变量的不同引用的解释
在main()函数里 创建的是 LinkList *L;
LinkLIst类型的指针变量 *L,变量L本身有地址,
作为指针变量也会存储 指向元素的地址
如 L=(LinkList *)malloc(sizeof(LinkList)); //创建头结点
L指向了 通过malloc 函数从内存里动态获取的一块区域的 地址
在主函数读取CreateListR(L,a,n);之前L没有储存地址不能用 *L
我的另外一篇转载博客 https://blog.csdn.net/Waybyway/article/details/83385551
在C语言里没有C++所谓的“按引用传递”,解释了C 和C++ 的不同
链表所有改变链表函数长度的函数如
一: 头插法,尾插法创建,初始化,销毁,插入,删除元素等函数用的参数是(LinkList *&L)
*&L表示 *是间接运算符 对&L(L本身的地址)间接运算,
二:其他函数参数都是(LinkList *L)
*/
/*单链表 头插法解释
在主函数main()中 的指针Linklist *L用来创建链表;
L为头结点,首地址存在这个里面了
L=(LinkList *)malloc(sizeof(LinkList)); //创建头结点
在输入之前现将他的指向置为 空NULL
通过malloc(sizeof(LinkList))动态分配sizeof(LinkList)的大小的空间
malloc函数的默认返还类型使 void类型,转换成 (LinkList *)类型
这样就创建了一个新结点 S
s->data=a[i]; s结点的data值被赋值为 a[i];
由于头结点 L->next=NULL,所以 s->next=L->next;
s->next 的指向也是NULL
L->next=S; 头结点 L指向了 第一个S (这个S记作 S_0)
这样头结点L就在 所有新结点的前面,最后使S_0结尾 指向为空
for(), 产生下一个 S_1
同样 S_1 的data被赋值,s->next=L->next;
上一步 L指向 S_0即上一个 S,这样S_1也指向了S_0
L->next=s; L这样就指向了 S_1
总之 S_0指向空,新的 S结点指向前一个 S结点
头结点L就在 所有新结点的前面,最后使S_0结尾 指向为空
最后生成的链表就是这样 链表 数值序列是 数组序列的逆序
L -> S_(N-1) -> S_(N-2) -> S_(N-3)……………… -> S_(1) -> S_(0) -> NULL
*/
void CreateListF(LinkList *&L,ElemType a[],int n)
//头插法建立单链表,将长度为N的数组 a[]创建为链表
{
LinkList *s;int i;
L=(LinkList *)malloc(sizeof(LinkList)); //创建头结点
L->next=NULL;
for (i=0;i<n;i++)
{
s=(LinkList *)malloc(sizeof(LinkList));//创建新结点
s->data=a[i];
s->next=L->next; //将*s插在原开始结点之前,头结点之后
L->next=s;
}
}
/*尾插法,部分解释与头插法不再叙述
L为头结点 ,指向为空
r=L; R 的指向也为空,R 的位置与L并列
产生新结点 S ,data被赋值为a[i]
r->next=s; //将*s插入*r之后
R 的位置与L并列
头结点L 指向 新产生的S结点 记作S_0
r=s; R 的位置与S_0并列
S_1产生 ,S_1的data被赋值
因为原来R与S_0并列,所以 r->next=s;
这样S_0就指向了S_1
最后一个S_(n-1)产生,R与他并列
最后指向空NULL
总之 R指针每次与新产生结点并列,让新结点指向下一个新结点
到最后一个结点 指向空
所以尾插法建立的链表 数值序列是 数组序列
L -> S_(0) -> S_(1) -> S_(2)……………… -> S_(N-2)-> S_(N-1) -> NULL
*/
void CreateListR(LinkList *&L,ElemType a[],int n)
//尾插法建立单链表
{
LinkList *s,*r;int i;
L=(LinkList *)malloc(sizeof(LinkList)); //创建头结点
L->next=NULL;
r=L; //r始终指向终端结点,开始时指向头结点
for (i=0;i<n;i++)
{
s=(LinkList *)malloc(sizeof(LinkList));//创建新结点
s->data=a[i];
r->next=s; //将*s插入*r之后
r=s;
}
r->next=NULL; //终端结点next域置为NULL
}
void InitList(LinkList *&L)
{
L=(LinkList *)malloc(sizeof(LinkList)); //创建头结点
L->next=NULL;
}
void DestroyList(LinkList *&L)
{
LinkList *p=L,*q=p->next;
while (q!=NULL)
{ free(p);
p=q;
q=p->next;
}
free(p); //此时q为NULL,p指向尾结点,释放它
}
bool ListEmpty(LinkList *L)
{
return(L->next==NULL);
}
int ListLength(LinkList *L)
{
LinkList *p=L;int i=0;
while (p->next!=NULL)
{ i++;
p=p->next;
}
return(i);
}
void DispList(LinkList *L)
{
LinkList *p=L->next;
while (p!=NULL)
{ printf("%d ",p->data);
p=p->next;
}
printf("\n");
}
bool GetElem(LinkList *L,int i,ElemType &e)
{
int j=0;
LinkList *p=L;
while (j<i && p!=NULL)
{ j++;
p=p->next;
}
if (p==NULL) //不存在第i个数据结点
return false;
else //存在第i个数据结点
{ e=p->data;
return true;
}
}
int LocateElem(LinkList *L,ElemType e)
{
LinkList *p=L->next;
int n=1;
while (p!=NULL && p->data!=e)
{ p=p->next;
n++;
}
if (p==NULL)
return(0);
else
return(n);
}
bool ListInsert(LinkList *&L,int i,ElemType e)
{
int j=0;
LinkList *p=L,*s;
while (j<i-1 && p!=NULL) //查找第i-1个结点
{ j++;
p=p->next;
}
if (p==NULL) //未找到位序为i-1的结点
return false;
else //找到位序为i-1的结点*p
{ s=(LinkList *)malloc(sizeof(LinkList));//创建新结点*s
s->data=e;
s->next=p->next; //将*s插入到*p之后
p->next=s;
return true;
}
}
bool ListDelete(LinkList *&L,int i,ElemType &e)
{
int j=0;
LinkList *p=L,*q;
while (j<i-1 && p!=NULL) //查找第i-1个结点
{ j++;
p=p->next;
}
if (p==NULL) //未找到位序为i-1的结点
return false;
else //找到位序为i-1的结点*p
{ q=p->next; //q指向要删除的结点
if (q==NULL)
return false; //若不存在第i个结点,返回false
e=q->data;
p->next=q->next; //从单链表中删除*q结点
free(q); //释放*q结点
return true;
}
}
二:含有主函数的Exam2-6.cpp文件
#include "linklist.cpp"
void delmaxnode(LinkList *&L)
{
LinkList *p=L->next,*pre=L,*maxp=p,*maxpre=pre;
while (p!=NULL) //用p扫描整个单链表,pre始终指向其前驱节点
{
if (maxp->data<p->data) //若找到一个更大的节点
{ maxp=p; //更改maxp
maxpre=pre; //更改maxpre
}
pre=p; //p、pre同步后移一个节点
p=p->next;
}
maxpre->next=maxp->next; //删除*maxp节点
free(maxp); //释放*maxp节点
}
int main()
{
LinkList *L;
int n=10;
ElemType a[]={1,3,2,9,0,4,7,6,5,8};
CreateListR(L,a,n);
printf("L:");DispList(L);
printf("删除最大值节点\n");
delmaxnode(L);
printf("L:");DispList(L);
DestroyList(L);
return 0;
}
两个文件需要在同一文件夹下,否则需要标示路径
今天就二级博客了,surprise,链表学会了,看见成长了