实现链表的增删,翻转
LinkList.h
#pragma once
typedef int DataType;
//链表节点信息
typedef struct LinkList {
DataType Pdata;
struct LinkList* next;
}LinkList,*PNode;
//链表的结构信息,给一个头指针保存链表第一个节点的地址
typedef struct PLink {
PNode PHead; //指针类型
}PLink;
// 链表的初始化
void LinkListInit(PLink* ps);
//创建一个新的节点
PNode CreateNewNode(DataType data);
// 在链表的尾部插入值为data的元素
void LinkListPushBack(PLink* ps, DataType data);
// 删除链表最后一个元素
void LinkListPopBack(PLink* ps);
// 在链表的头部插入值为data的元素
void LinkListPushFront(PLink* ps, DataType data);
// 删除链表头部的元素
void LinkListPopFront(PLink* ps);
// 在链表pos位置插入值为data的元素
void LinkListInsert( PNode pos, DataType data);
// 删除链表中pos位置上的元素
void LinkListErase(PLink* ps,PNode pos);
// 在链表中查找值为data的元素,找到返回该元素在链表中的地址,否则返回NULL,返回的地址00000000
PNode LinkListFind(PLink* ps, DataType data);
// 检测链表是否为空,如果为空返回非0值,非空返回0
int LinkListEmpty(PLink* ps);
// 返回链表中节点的的个数
int LinkListSize(PLink* ps);
//链表翻转
PNode LinkListReturn(PLink* ps);
// 删除链表中第一个值为data的元素
void LinkListRemove(PLink* ps, DataType data);
// 销毁链表
void LinkListDestroy(PLink* ps);
//打印
void LinkListPrint(PLink* ps);
LinkList.c
// 链表的初始化
void LinkListInit(PLink* ps) {
assert(ps);
ps->PHead = NULL;
}
//创建一个新的节点
PNode CreateNewNode(DataType data) {
PNode PnewNode = (PNode)malloc(sizeof(LinkList));
if (PnewNode == NULL) {
return NULL;
}
PnewNode->Pdata = data;
PnewNode->next = NULL;
return PnewNode;
}
// 在链表的尾部插入值为data的元素
void LinkListPushBack(PLink* ps, DataType data) {
assert(ps);
PNode PnewNode = CreateNewNode(data);
//链表为空
if (ps->PHead == NULL) {
ps->PHead = PnewNode;
}
//链表不为空
else {
PNode Ptmp = ps->PHead;
while(Ptmp->next != NULL) {
Ptmp = Ptmp->next;
}
Ptmp->next= PnewNode;
}
}
//删除链表最后一个元素
void LinkListPopBack(PLink* ps) {
assert(ps);
//ps中没节点
if (ps->PHead == NULL) {
return;
}
//ps只有一个节点
if (ps->PHead->next == NULL) {
free(ps->PHead);
ps->PHead = NULL;
}
//ps有多个节点
PNode Pptr = NULL;
PNode Ptmp = ps->PHead;
while (Ptmp->next != NULL) {
Pptr = Ptmp;
Ptmp = Ptmp->next;
}
free(Ptmp);
Pptr->next = NULL;
}
// 在链表的头部插入值为data的元素
void LinkListPushFront(PLink* ps, DataType data) {
assert(ps);
PNode PnewNode = CreateNewNode(data);
PnewNode->next = ps->PHead;
ps->PHead = PnewNode;
}
// 删除链表头部的元素
void LinkListPopFront(PLink* ps) {
assert(ps);
if (ps->PHead == NULL) {
return;
}
PNode Ptmp = ps->PHead;
ps->PHead = ps->PHead->next;
free(Ptmp);
}
// 在链表pos位置插入值为data的元素 (在pos的后面)
void LinkListInsert( PNode pos, DataType data) {
if (pos == NULL) {
return;
}
PNode PNewNode = CreateNewNode(data);
PNewNode->next = pos->next;
pos->next = PNewNode;
}
// 删除链表中pos位置上的元素
void LinkListErase(PLink* ps, PNode pos) {
assert(ps);
if (pos == NULL || ps->PHead == NULL) {
return;
}
if (pos == ps->PHead) {
ps->PHead = pos->next;
}
else {
PNode Ppos = ps->PHead;
while (Ppos != NULL && Ppos->next != pos) {
Ppos = Ppos->next;
}
if(Ppos!=NULL){
Ppos->next = pos->next;
}
}
free(pos);
}
// 在链表中查找值为data的元素,找到返回该元素在链表中的地址,否则返回NULL,返回的地址00000000
PNode LinkListFind(PLink* ps, DataType data) {
assert(ps);
PNode Ptmp = ps->PHead;
while (Ptmp!=NULL) {
if (Ptmp->Pdata == data) {
return Ptmp;
}
Ptmp = Ptmp->next;
}
return NULL;
}
// 返回链表中节点的的个数
int LinkListSize(PLink* ps) {
assert(ps);
size_t count = 0;
PNode Ptmp = ps->PHead;
while (Ptmp != NULL) {
count++;
Ptmp = Ptmp->next;
}
return count;
}
//检测链表是否为空,如果为空返回非0值,非空返回0
int LinkListEmpty(PLink* ps) {
assert(ps);
if (ps->PHead == NULL)
return 1;
return 0;
}
// 删除链表中第一个值为data的元素
void LinkListRemove(PLink* ps, DataType data) {
PNode Pptr = NULL;
PNode Ptmp = ps->PHead;
while (Ptmp) {
if (Ptmp->Pdata == data) {
if (Ptmp == ps->PHead) {
ps->PHead = Ptmp->next;
}
else {
Pptr->next = Ptmp->next;
}
free(Ptmp);
return;
}
Pptr = Ptmp;
Ptmp = Ptmp->next;
}
}
//链表反转
PNode LinkListReturn(PLink* ps) {
assert(ps);
PNode Pptr = NULL; //
PNode Ptmp =ps->PHead;
while (Ptmp != NULL) {
PNode next = Ptmp->next;
//头插,形成反转
Ptmp->next =Pptr ;
Pptr = Ptmp;
Ptmp = next;
}
return Pptr;
}
// 销毁链表
void LinkListDestroy(PLink* ps) {
assert(ps);
PNode Pptr = ps->PHead->next;
PNode Ptmp = ps->PHead;
while (Pptr != NULL) {
free(Ptmp);
Ptmp = Pptr;
Pptr = Pptr->next;
}
free(Ptmp);
}
//打印
void LinkListPrint(PLink* ps) {
assert(ps);
PNode Ptmp = ps->PHead;
while (Ptmp!=NULL) {
printf("%d->", Ptmp->Pdata);
Ptmp = Ptmp->next;
}
printf("NULL\n");
}
void main() {
PLink ps;
// 链表的初始化
LinkListInit(&ps);
// 在链表的尾部插入值为data的元素
LinkListPushBack(&ps, 1);
LinkListPushBack(&ps, 2);
LinkListPushBack(&ps, 3);
LinkListPushBack(&ps, 4);
LinkListPushBack(&ps, 5);
LinkListPrint(&ps); //打印,查看结果
// 删除链表最后一个元素
LinkListPopBack(&ps);
LinkListPrint(&ps); //打印,查看结果
// 在链表的头部插入值为data的元素
LinkListPushFront(&ps,0);
LinkListPrint(&ps); //打印,查看结果
// 删除链表头部的元素
LinkListPopFront(&ps);
LinkListPrint(&ps); //打印,查看结果
// 在链表pos位置插入值为data的元素
LinkListInsert(LinkListFind(&ps, 1) ,1);
LinkListPrint(&ps); //打印,查看结果
// 删除链表中pos位置上值为data的元素
LinkListErase(&ps, LinkListFind(&ps, 1));
LinkListPrint(&ps); //打印,查看结果
// 在链表中查找值为data的元素,找到返回该元素在链表中的位置,否则返回NULL,返回的地址00000000
//此处结果, 返回结果为函数 LinkListInsert(); 的第一个参数
//此处结果, 返回结果为函数 LinkListErase(); 的第二个参数
printf("%p\n", LinkListFind(&ps, 5)); //打印地址
// 返回链表中节点的的个数
int ret=LinkListSize(&ps);
printf("节点有%d个\n",ret);
// 检测链表是否为空,如果为空返回1,非空返回0
int rte=LinkListEmpty(&ps);
printf("rte=%d\n", rte);
//链表反转
printf("反转前的链表:");
LinkListPrint(&ps);
PNode result= LinkListReturn(&ps);
printf("反转后的链表:");
while (result != NULL) {
printf("%d->", result->Pdata);
result = result->next;
}
printf("NULL\n");
//删除链表中第一个值为data的元素
LinkListRemove(&ps, 2);
LinkListPrint(&ps);
// 销毁链表
LinkListDestroy(&ps);
system("pause");
}