练习使用双向链表(实现增删改查)
是指针指向了一块被释放的空间
解决方案:
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->prev
phead->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->next
phead->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;
//处理phead
phead->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;
}