文章目录
1.单链表
1.1 单链表的创建
typedef struct LNode
{
int data;
struct LNode* next;
}LNode, * LinkList;
1.2单链表的初始化
int InitLinkList(LinkList *L)
{
*L = (LinkList)malloc(sizeof(LNode));//为头结点分配空间
if (*L == NULL)
{
printf("开辟内存空间失败,初始化头结点失败");
return -1;
}
(*L)->next = NULL;
return 0;
}
1.3打印单链表
int printLinkList(LinkList *L) {
LNode* p = *L; //p为指向当前结点的指针
//判断链表是否为空
if (p->next == NULL) {
printf("该链表为空");
return -1;
}
while (p->next!=NULL)
{
p = p->next;//跳过头结点
printf("%d ",p->data);
}
return 0;
}
1.4头插建立单链表
1.4.1 原理图
注意: 原理图中的代码表示和代码并不对应
1.4.2代码
int headInsert(LinkList* L, int n)
{
LNode* p = *L;
LNode* pnew = NULL;//新的节点
for (int i = 0; i < n; i++)
{
pnew = (LinkList)malloc(sizeof(LNode));
if (pnew == NULL)
{
printf("error");
return -1;
}
int num = 0;
printf("请输入:");
scanf("%d", &num);
pnew->data = num;//将数据插入到新的节点中
pnew->next = (*L)->next;//新的节点的指针域指向头结点的下一个结点
(*L)->next = pnew;//头结点指针域指向新的结点
}
return 0;
}
1.4.3测试头插
int main() {
//定义并初始化单链表
LinkList p = NULL;
//初始化单链表
InitLinkList(&p);
int n = 5;//插入元素个数
headInsert(&p, n);//头插
printLinkList(&p);//打印单链表中的元素
return 0;
}
1.4.4运行结果
1.5 头删
1.5.1原理
1.5.2代码
int delHead(LinkList* L)
{
LNode* pdel = NULL;//存储删除结点
//首先对表进行判空
if ((*L)->next == NULL)
{
printf("空表不能删除");
return -1;
}
pdel = (*L)->next;//要删除的结点
(*L)->next = pdel->next;//令头结点的next指向要删除的结点的下一个节点
free(pdel);//释放删除结点的内存
return 0;
}
1.5.3测试头删
int main() {
//定义并初始化单链表
LinkList p = NULL;
//初始化单链表
InitLinkList(&p);
int n = 5;//插入元素个数
headInsert(&p, n);//头插
printf("头删前单链表元素:\n");
printLinkList(&p);
delHead(&p);//头删
printf("\n头删后单链表元素:\n");
printLinkList(&p);
return 0;
}
1.5.4运行结果
1.6尾插建立单链表
1.6.1原理图
由图可知,尾插每一次都把新的结点插入到单链表的最后
1.6.2代码
int InsertLinkListTail(LinkList* L,int n)
{
LNode* pnew = NULL;
LNode* ptail = *L;
for (int i = 0; i < n; i++)
{
pnew = (LinkList)malloc(sizeof(LNode));
if (pnew == NULL)
{
printf("error");
return -1;
}
int num = 0;
printf("请输入:");
scanf("%d", &num);
pnew->data = num;
pnew->next = NULL;
ptail->next = pnew;
ptail = pnew;//尾节点后移
}
return 0;
}
1.6.3测试代码
int main() {
//定义并初始化单链表
LinkList p = NULL;
//初始化单链表
InitLinkList(&p);
int n = 5;//插入元素个数
InsertLinkListTail(&p, n);//尾插
printLinkList(&p);
return 0;
}
1.6.4运行结果
1.7尾删
尾删是每一次删除单链表的最后一个结点
1.7.1原理图
1.7.2代码
int delTail(LinkList* L)
{
//LNode* p = *L;
LNode* tail = *L;//指向头结点
if (tail == NULL)
{
printf("错误");
return -1;
}
LNode* pre = NULL;
while (tail->next!=NULL)
{
pre = tail;//循环结束后指向尾结点前一个结点
tail = tail->next;//指向尾结点
}
pre->next = NULL;//删除尾节点
free(tail);//释放尾节点空间
return 0;
}
1.7.3测试代码
int main() {
//定义并初始化单链表
LinkList p = NULL;
//初始化单链表
InitLinkList(&p);
//尾插法插入10个节点
int n = 5;//插入元素个数
InsertLinkListTail(&p, n);//尾插建立单链表
printf("尾删前单链表元素:");
printLinkList(&p);
delTail(&p);//尾删
printf("\n尾删后单链表元素:");
printLinkList(&p);
return 0;
}
1.7.4运行结果
运行结果可知,尾节点被删除了
1.8插入结点(按位置插入)
在单链表任意位置插入一个结点
1.8.1原理图
1.8.2代码
int insertNode(LinkList *L,int i,int e)
{
//判断插入位置是否合法
if (i < 1)
return -1;
LNode* p = *L; //p为指向当前结点的指针
int j = 0; //p指针指向的当前结点,当前位置为头结点
//寻找i-1个节点
while (p != NULL && j < i - 1) {
p = p->next;
j++;
}
LNode* s = (LNode*)malloc(sizeof(LNode)); //创建新结点
if (s == NULL)
{
return -1;
}
s->data = e;
s->next = p->next;
p->next = s;
return 0;
}
1.8.3测试代码
int main() {
//定义并初始化单链表
LinkList p = NULL;
//初始化单链表
InitLinkList(&p);
//尾插法插入5个节点
int n = 5;//插入元素个数
InsertLinkListTail(&p, n);//尾插建立单链表
printf("插入结点前单链表元素:");
printLinkList(&p);
//在p中第i个元素之前插入数据元素e
insertNode(&p, 5, 66);
printf("\n插入结点后单链表元素:");
printLinkList(&p);
return 0;
}
1.8.4运行结果
1.9删除结点
删除单链表中任意位置的结点
1.9.1原理图
1.9.2代码
//删除链表中某个位置的元素
int DeleteList(LinkList* L, int i, int* temp)
{
LNode* pre,*p; //pre指向被删除结点的前一个结点,p指向被删除节点
pre = *L;
int j = 0;
//查找第i-1个节点
while (pre != NULL && j < i-1) {
pre = pre->next;
j++;
}
//判断删除位置是否合法
if (pre->next==NULL || j > i - 1)
{
printf("删除位置不合理!!");
return -1;
}
p = pre->next;
pre->next = p->next; //改变删除结点前驱结点的指针域
*temp = p->data;//删除结点的数据域中的数据存放在temp中
free(p);//释放删除结点的空间
return 0;
}
1.9.3测试代码
int main() {
//定义并初始化单链表
LinkList p = NULL;
//初始化单链表
InitLinkList(&p);
//尾插法插入5个节点
int n = 5;//插入元素个数
InsertLinkListTail(&p, n);//尾插建立单链表
printf("删除结点前单链表元素:");
printLinkList(&p);
int delEle = 3;//删除第几个元素
int temp = 0;//用于存储删除元素
DeleteList(&p, delEle, &temp);
printf("\n删除第%d个位置的元素为:%d\n", delEle, temp);
printf("删除结点后单链表元素:");
printLinkList(&p);
return 0;
}
1.9.4运行结果
2.0按位置查找元素
2.0.1代码
//获取链表中的某一个位置的元素
int GetElem(LinkList* L, int i, int* e)
{
LNode* p = *L; //p指针用于指向链表的首结点
int length = ListLength(L);//表长
if(i<1||i>length)
{
printf("查找位置不合法");
return -1;
}
int j = 0;
//查找第七个元素,下标为6,所以让p指针指向下表为6的结点
while (p != NULL && j < i) {
p = p->next;
j++;
}
//当前结点的数据域中就是所要查找的元素
*e = p->data;
return 0;
}
2.0.2测试代码
int main() {
//定义并初始化单链表
LinkList p = NULL;
//初始化单链表
InitLinkList(&p);
//尾插法插入7个节点
int n = 7;//插入元素个数
InsertLinkListTail(&p, n);//尾插建立单链表
printf("单链表中的元素:");
printLinkList(&p);
//查找元素(查找第七个位置的元素,并把元素存在变量e中)
int e = 0;//用于接收查找到的数据
int i = 4;//查找第几个位置的元素
GetElem(&p, i, &e);
printf("\n第%d个位置的元素为:%d",i,e);
return 0;
}
2.0.3运行结果
2.1按值查找元素
2.1.1代码
//按照值查找
int locatePos(LinkList* L, int e)
{
LNode* p = *L;//指向头结点
int i = 0;
int temp = 0;
//从头结点开始查找
while (p!=NULL)
{
//找到e后
if (p->data == e)
{
printf("找到了%d元素,是第%d个元素",e,i);
temp = p->data;
}
//未找到e
i++;//因为有首结点,所以i的值就是第几个位置
p = p->next;//指针移动到下一个节点
}
if (temp != e)
{
printf("未找到%d元素",e);
}
}
2.1.2测试代码
int main() {
//定义并初始化单链表
LinkList p = NULL;
//初始化单链表
InitLinkList(&p);
//尾插法插入7个节点
int n = 7;//插入元素个数
InsertLinkListTail(&p, n);//尾插建立单链表
printf("单链表中的元素:");
printLinkList(&p);
locatePos(&p, 5);//查找为5的元素(按值查找)
return 0;
}
2.1.3运行结果
2.2求链表的长度
2.2.1代码
int ListLength(LinkList* L)
{
LNode* p = *L; //p指针用于指向链表的首结点
int LinkListlegth = 0;
while (p->next != NULL)
{
p = p->next;
LinkListlegth++;
}
return LinkListlegth;
}
2.2.2测试代码
int main() {
//定义并初始化单链表
LinkList p = NULL;
//初始化单链表
InitLinkList(&p);
//尾插法插入7个节点
int n = 7;//插入元素个数
InsertLinkListTail(&p, n);//尾插建立单链表
//打印节点元素
printf("单链表中的元素:");
printLinkList(&p);
//求链表的长度
int length = ListLength(&p);
printf("\n链表长度为:%d\n", length);
return 0;
}
2.2.3运行结果
2.3销毁链表
先删除 除了头结点之外的结点,最后把头结点删除
2.3.1代码
这里我使用了无限头删的方法清空单链表,最后把头结点删除,为了测试出结果我把删除头结点的操作注释了
//销毁链表
int destoryLinkList(LinkList* L)
{
LNode* p = *L;
LNode* q = NULL;
while (p->next != NULL)
{
q = p->next;
p->next = q->next;
free(q);
}
//干掉头结点,这里我为了测试就先不删除头结点了
//free(*L);
return 0;
}
2.3.2测试代码
int main() {
//定义并初始化单链表
LinkList p = NULL;
//初始化单链表
InitLinkList(&p);
//尾插法插入7个节点
int n = 7;//插入元素个数
InsertLinkListTail(&p, n);//尾插建立单链表
printf("销毁前单链表中的元素:");
printLinkList(&p);
destoryLinkList(&p);
printf("\n销毁后单链表中的元素:");//为了测试没有删除头结点
printLinkList(&p);
return 0;
}