双向链表(实现增删改查)"/>
c语言练习95:练习使用双向链表(实现增删改查)
练习使用双向链表(实现增删改查)
是指针指向了一块被释放的空间
解决方案:
plist=NULL
List.h
#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>
//定义双向链表结点的结构
typedef int LTDataType;
typedef struct ListNode {LTDataType data;struct ListNode* next;struct ListNode* prev;
}LTNode;
//传入一个头结点
//void LTInit(LTNode** pphead);//pphead保存plist的地址
LTNode* LTInit();//不需要传入参数,调用该方法后返回一个头结点
//双向链表中不会改变哨兵卫,所以这里都可以传一级指针
//插入删除操作
//尾插
void LTPushBack(LTNode* phead, LTDataType x);
//头插
void LTPushFront(LTNode* phead, LTDataType x);
//尾删
void LTPopBack(LTNode* phead);
//头删
void LTPopFront(LTNode* phead);
//在pos位置之后插入数据
void LTInsert(LTNode* pos, LTDataType x);
void LTErase(LTNode* pos);
LTNode* LTFind(LTNode* phead, LTDataType x);
//销毁
void LTDistory(LTNode* phead);
//void Distory(LTNode** phead);
//
//打印
void LTPrint(LTNode* phead);
List.c
#define _CRT_SECURE_NO_WARNINGS
#include"List.h"
//传入一个头结点
//void LTInit(LTNode** pphead) {//头结点指针的地址
// //申请结点
// *pphead = (LTNode*)malloc(sizeof(LTNode));
// if (*pphead == NULL) {
// perror("malloc fail!\n");
// return;
// }
// //结点包括三部分:数据,(前驱,后记)指针
// (*pphead)->data = -1;//哨兵卫
// (*pphead)->next = (*pphead)->prev = *pphead;
//
//}
//不需要传入参数,调用该方法后返回一个头结点
LTNode* LTInit() {LTNode* phead = (LTNode*)malloc(sizeof(LTNode));if (phead == NULL) {perror("malloc fail\n");return;}phead->data = -1;phead->next = phead->prev = phead;return phead;
}
LTNode*ListBuyNode(LTDataType x) {LTNode* node = (LTNode*)malloc(sizeof(LTNode));node->data = x;node->next = node->prev = NULL;return node;
}
//插入删除操作
void LTPushBack(LTNode* phead, LTDataType x) {assert(phead);LTNode* node = ListBuyNode(x);//处理node的前驱和后继指针node->prev = phead->prev;node->next = phead;//处理phead和之前的尾结点phead->prevphead->prev->next = node;phead->prev = node;
}
//头插
void LTPushFront(LTNode* phead, LTDataType x) {assert(phead);LTNode*node= ListBuyNode(x);//处理node的前驱和后继指针node->prev = phead;node->next = phead->next;//处理phead和之前的尾结点phead->nextphead->next->prev = node;phead->next = node;
}
//尾删
void LTPopBack(LTNode* phead) {assert(phead);assert(phead->next != phead);LTNode* del = phead->prev;//处理del的prev结点del->prev->next = phead;//处理pheadphead->prev = del->prev;free(del);del = NULL;
}
//头删
void LTPopFront(LTNode* phead) {LTNode* del = phead->next;assert(phead);assert(phead->next != phead);del->next->prev = phead;phead->next = del->next;free(del);del = NULL;
}
//在pos位置之后插入数据
void LTInsert(LTNode* pos, LTDataType x) {assert(pos);LTNode* node = ListBuyNode(x);node->next = pos->next;node->prev = pos;pos->next = node;node->next->prev = node;
}
void LTErase(LTNode* pos) {assert(pos);pos->next->prev = pos->prev;pos->prev->next = pos->next;free(pos);pos = NULL;
}
LTNode* LTFind(LTNode* phead, LTDataType x) {assert(phead);LTNode* cur = phead->next;while (cur != phead) {if (cur->data == x) {return cur;}cur = cur->next;}return NULL;
}
//销毁
void LTDistory(LTNode* phead) {assert(phead);LTNode* cur = phead->next;while (cur != phead) {LTNode* next = cur->next;free(cur);cur = next;}free(phead);phead = NULL;
}
//void Distory(LTNode** pphead) {
//assert(pphead&&* pphead);
//LTNode* cur = (*pphead)->next;
//while (cur != *pphead) {
// LTNode* next = cur->next;
// free(cur);
// cur = next;
//}
//free(*pphead);
//*pphead = NULL;
//}
//打印
void LTPrint(LTNode* phead) {LTNode* cur = phead->next;while (cur != phead) {printf("%d->", cur->data);cur = cur->next;}printf("\n");
}
test.c
#include"List.h"
#define _CRT_SECURE_NO_WARNINGS
void ListTest() {//LTNode* plist = NULL;//LTInit(&plist);LTNode* plist =LTInit();LTPushBack(plist, 1);LTPushBack(plist, 2);LTPushBack(plist, 3);LTPushBack(plist, 4);LTPrint(plist);// 1 2 3 4//LTPushFront(plist, 5);//LTPushFront(plist, 6);//LTPushFront(plist, 7);//LTPrint(plist);//7 6 5 1 2 3 4//LTPopBack(plist);//LTPopBack(plist);//LTPopBack(plist);//LTPopBack(plist);//LTPopBack(plist);//LTPopFront(plist);//LTPopFront(plist);//LTPopFront(plist);//LTPopFront(plist);//LTPopFront(plist);测试指定位置之后插入//LTNode* find = LTFind(plist, 1);LTInsert(find, 11);//LTErase(find);//LTPrint(plist);//LTDestroy(&plist);//LTDestroy(plist);//传一级指针的时候需要手动将plist置为空plist = NULL;
}int main()
{ListTest();return 0;
}
更多推荐
c语言练习95:练习使用双向链表(实现增删改查)
发布评论