c语言练习95:练习使用双向链表(实现增删改查)

练习使用双向链表(实现增删改查)

c语言练习95:练习使用双向链表(实现增删改查)_第1张图片

c语言练习95:练习使用双向链表(实现增删改查)_第2张图片

 c语言练习95:练习使用双向链表(实现增删改查)_第3张图片

c语言练习95:练习使用双向链表(实现增删改查)_第4张图片

c语言练习95:练习使用双向链表(实现增删改查)_第5张图片

是指针指向了一块被释放的空间 

解决方案:

plist=NULL

c语言练习95:练习使用双向链表(实现增删改查)_第6张图片

c语言练习95:练习使用双向链表(实现增删改查)_第7张图片

c语言练习95:练习使用双向链表(实现增删改查)_第8张图片

c语言练习95:练习使用双向链表(实现增删改查)_第9张图片

c语言练习95:练习使用双向链表(实现增删改查)_第10张图片

c语言练习95:练习使用双向链表(实现增删改查)_第11张图片

c语言练习95:练习使用双向链表(实现增删改查)_第12张图片c语言练习95:练习使用双向链表(实现增删改查)_第13张图片 

c语言练习95:练习使用双向链表(实现增删改查)_第14张图片c语言练习95:练习使用双向链表(实现增删改查)_第15张图片

c语言练习95:练习使用双向链表(实现增删改查)_第16张图片

List.h

#pragma once
#define  _CRT_SECURE_NO_WARNINGS 
#include
#include
#include
#include
//定义双向链表结点的结构
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;
}

“error LNK2019: 无法解析的外部符号”原因总结_lnk2019无法解析的外部符号-CSDN博客

c语言练习95:练习使用双向链表(实现增删改查)_第17张图片

你可能感兴趣的:(c语言,链表,开发语言)