链表 (单向)
单向链表、单向循环链表、双向链表、双向循环链表
开辟的是单个的存储空间,通过地址将他们联系在一起。
逻辑结构:线性结构
存储结构:链式存储
单向:
1.有头单向链表
链表中的头节点数据域无效,指针域有效。
2.无头单向链表
所有节点的数据域和指针域都是有效的。
Link List.c
/**
** Created by 24122 on 2022/4/23.
**/
#include <stdio.h>
#include <stdlib.h>
#include "LinkList.h"
/**
* 1.创建一个空的有头的单链表
*/
link_t *CreateLinkList(void)
{
//1.开辟一个头节点,data无效,next有效
link_t *p = (link_t *) malloc(sizeof (link_t));
//2.判断结点是否开辟成功
if(p == NULL)
{
printf("CreateLinkList error!\n");
return NULL;
}
//3.next有效
p->next =NULL;
return p;
}
/**
* 2.链表指定位置插入元素
*/
int LinkListPostInsert(link_t *p,int post,datatype data)
{
link_t *pnew =NULL;
//1.容错判断
if(post < 0 || post > LinkListLength(p))
{
printf("LinkListPostInsert error\n");
return -1;
}
//2.开辟一个结点空间保存要插入的数据
pnew =(link_t *) malloc(sizeof (link_t));
if(pnew ==NULL)
{
printf("malloc pnew error!\n");
return -1;
}
//3.初始化结点内容
pnew->data=data;
pnew->next =NULL;
//4.将头指针移动到要插入的前一个位置
for (int i = 0; i < post; i++) {
p=p->next;
}
//5,插入新元素:先连后面,在连前面
pnew->next=p->next;
p->next = pnew;
return 0;
}
/**
* 3.删除指定位置的元素
*/
int LinkListDeletePost(link_t *p,int post)
{
link_t *pdel = NULL;
//1.容错判断
if(post <0 ||post > LinkListLength(p) -1|| LinkListIsEmpty(p))
{
printf("LinkListDeletePost error!\n");
return -1;
}
//2.把头指针移动到要删除的前一个位置
for (int i = 0; i < post; i++) {
p=p->next;
}
//3.定义一个指针保存要删除的元素结点的地址
pdel =p->next;
//4.删除操作
p->next = pdel->next;
free(pdel);
pdel=NULL;
return 0;
}
/**
*4.判断链表否为空
*/
int LinkListIsEmpty(link_t *p)
{
return p->next == NULL; //1:空 2:非空
}
/**
* 5.遍历有头单向链表
*/
void ShowLinkList(link_t *p)
{
while (p->next !=NULL)
{
p = p->next;
printf("%d ", p->data);
}
putchar(10);
}
/**
* 6.计算链表长度
*/
int LinkListLength(link_t *p)
{
int length=0;
while(p->next !=NULL)
{
length++;
p=p->next;
}
return length;
}
/**
* 7.查询链表的指定位置的数据
*/
datatype LinkListSearchPost(link_t *p ,int post)
{
//1.容错判断
if(post <0 ||post > LinkListLength(p)-1 || LinkListIsEmpty(p))
{
printf("LinkListSearchPost error!\n");
return -1;
}
//2.移动头指针到post位置
for (int i = 0; i <= post; i++) {
p=p->next;
}
return p->data;
}
/**
* 8.查询指定数据在链表的位置
*/
int LinkListSearchData(link_t *p,datatype data)
{
int post=0;
while(p->next!=NULL)
{
p=p->next;
if(p->data==data)
return post;
post++;
}
return -1;
}
/**
* 9.修改链表中指定的数据
*/
int LinkListChangeData(link_t *p,datatype olddata,datatype newdata)
{
if(LinkListIsEmpty(p))
{
printf("9.LinkListChangeData Empty!\n");
return -1;
}
while (p->next != NULL)
{
p=p->next;
if(p->data ==olddata)
{
p->data=newdata;
}
}
return 0;
}
/**
* 10.修改链表中指定位置的数据
*/
int LinkListChangePost(link_t *p,int post,datatype data)
{
//1。容错判断
if(post <0 ||post> LinkListLength(p)-1|| LinkListIsEmpty(p))
{
printf("LinkListChangePost error\n");
return -1;
}
//2.移动到post位置
for (int i = 0; i <= post; i++) {
p=p->next;
}
p->data=data;
return 0;
}
/**
* 11.删除链表中指定的数据
*/
int LinkListDeleteData(link_t *p,datatype data)
{
link_t *pdel =NULL;
if(LinkListIsEmpty(p))
{
printf("LinkListDeleteData error!\n");
return -1;
}
while(p->next!=NULL)
{
if(p->next->data == data)
{
pdel=p->next;
p->next = pdel->next;
free(pdel);
pdel=NULL;
} else{
p=p->next;
}
}
return 0;
}
/**
* 12.链表的转置 1 2 3 4 5 5 4 3 2 1
*/
int LinkListInvert(link_t *p)
{
link_t *pt = NULL;//保存头节点地址
//断成两个链表
link_t *pa = p->next;//保存无头的链表
p->next=NULL;//让p断开,p保存有头空链表头节点地址
//2.遍历无头单向链表砍头插入到有头空链表头节点之前
while (pa != NULL)
{
//断开头节点
pt=pa;
pa = pa->next;
pt->next=NULL;
//将pt插入到p链表0的位置
pt->next=p->next;
p->next=pt;
}
return 0;
}
/**
* //13.清空链表
*/
void LinkListClear(link_t *p)
{
while (!LinkListIsEmpty(p))
{
LinkListDeletePost(p,0);
}
}
/**
* 14.销毁链表
*/
int LinkListDestroy(link_t *p)
{
link_t *q =NULL;
link_t *r =NULL;
if(p==NULL){
return -1;
}
q=p->next;
while(q !=NULL)
{
r=q->next;
free(q);
q=r;
}
p->next=NULL;
return 0;
}
LinkList.h
/**
** Created by 24122 on 2022/4/23.
**/
#ifndef DATASTRUCTURE_LINKLIST_H
#define DATASTRUCTURE_LINKLIST_H
typedef int datatype;
typedef struct node_t
{
datatype data;
struct node_t *next;
}link_t,*link_p;
/**
* 1.创建一个空的有头的单链表
*/
link_t *CreateLinkList(void);
/**
* 2.链表指定位置插入元素
*/
int LinkListPostInsert(link_t *p,int post,datatype data);
/**
* 3.删除指定位置的元素
*/
int LinkListDeletePost(link_t *p,int post);
/**
*4.判断链表否为空
*/
int LinkListIsEmpty(link_t *p);
/**
* 5.遍历有头单向链表
*/
void ShowLinkList(link_t *p);
/**
* 6.计算链表长度
*/
int LinkListLength(link_t *p);
/**
* 7.查询链表的指定位置的数据
*/
datatype LinkListSearchPost(link_t *p ,int post);
/**
* 8.查询指定数据在链表的位置
*/
int LinkListSearchData(link_t *p,datatype data);
/**
* 9.修改链表中指定的数据
*/
int LinkListChangeData(link_t *p,datatype olddata,datatype newdata);
/**
* 10.修改链表中指定位置的数据
*/
int LinkListChangePost(link_t *p,int post,datatype data);
/**
* 11.删除链表中指定的数据
*/
int LinkListDeleteData(link_t *p,datatype data);
/**
* 12.链表的转置 1 2 3 4 5 5 4 3 2 1
*/
int LinkListInvert(link_t *p);
/**
* //13.清空链表
*/
void LinkListClear(link_t *p);
/**
* 14.销毁链表
*/
int LinkListDestroy(link_t *p);
#endif //DATASTRUCTURE_LINKLIST_H
main.c
/**
** Created by 24122 on 2022/4/23.
**/
#include <stdlib.h>
#include <stdio.h>
#include "LinkList.h"
int main(){
/* link_t *p = CreateLinkList();
//插入
LinkListPostInsert(p,0,1);
LinkListPostInsert(p,1,2);
LinkListPostInsert(p,2,3);
LinkListPostInsert(p,3,4);
LinkListPostInsert(p,4,5);
//遍历
ShowLinkList(p);
//删除
LinkListDeletePost(p,2);
LinkListDeleteData(p,4);
//遍历
ShowLinkList(p);
LinkListPostInsert(p,2,3);
LinkListPostInsert(p,3,4);
//遍历
ShowLinkList(p);
//查询
int i=LinkListSearchPost(p,2);
printf("%d\n",i);
int j =LinkListSearchData(p,2);
printf("%d\n",j);
//修改
LinkListChangeData(p,3,30);
LinkListChangePost(p,1,20);
//遍历
ShowLinkList(p);
LinkListInvert(p);
//遍历
ShowLinkList(p);
LinkListClear(p);
//遍历
ShowLinkList(p);
//销毁
LinkListDestroy(p);
return 0;
*/
//两个链表按顺序拼接
link_t *p = CreateLinkList();
link_t *q = CreateLinkList();
link_t *r = CreateLinkList();
LinkListPostInsert(p,0,1);
LinkListPostInsert(p,1,3);
LinkListPostInsert(p,2,5);
LinkListPostInsert(p,3,7);
LinkListPostInsert(p,4,9);
LinkListPostInsert(p,5,10);
LinkListPostInsert(q,0,2);
LinkListPostInsert(q,1,4);
LinkListPostInsert(q,2,5);
LinkListPostInsert(q,3,8);
LinkListPostInsert(q,4,11);
LinkListPostInsert(q,5,15);
ShowLinkList(p);
ShowLinkList(q);
int count=0;
p=p->next;
q=q->next;
while (p!=NULL&&q!=NULL)
{
if(p->data < q->data)
{
LinkListPostInsert(r,count,p->data);
p=p->next;
} else
{
LinkListPostInsert(r,count,q->data);
q=q->next;
}
count++;
}
while(p!=NULL)
{
LinkListPostInsert(r,count++,p->data);
p=p->next;
}
while (q!=NULL){
LinkListPostInsert(r,count++,q->data);
q=q->next;
}
ShowLinkList(r);
}