所属专栏:初始数据结构
博主首页:初阳785
代码托管:chuyang785
感谢大家的支持,您的点赞和关注是对我最大的支持!!!
博主也会更加的努力,创作出更优质的博文!!
关注我,关注我,关注我,重要的事情说三遍!!!!!!!!
//防止头文件重复定义
#pragma once
#include
//断言
#include
//动态内存malloc头文件
#include
//存储数据类型类型
typedef int LTDateType;
typedef struct ListNode
{
//存储数据
LTDateType data;
//记录下一个节点
struct ListNode* next;
//记录前一个节点
struct ListNode* prev;
}LTNode;
//初始化
LTNode* ListInit();
//链表打印
void ListPrint(LTNode* phead);
//尾插
void ListPushBack(LTNode* phead, LTDateType x);
//尾删
void ListPopBack(LTNode* phead);
//头插
void ListPushFront(LTNode* phead, LTDateType x);
//头删
void ListPopFront(LTNode* phead);
//查找
LTNode* ListFind(LTNode* phead,LTDateType x);
//给定位置插入
LTNode* ListTnsert(LTNode* pos, LTDateType x);
//给定位置删除
LTNode* ListErase(LTNode* pos);
//释放空间
void ListDestroy(LTNode* phead);
LTNode* ListInit()
{
//设置哨兵为
LTNode* phead = (LTNode*)malloc(sizeof(LTNode));
if (phead != NULL)
{
phead->next = phead;
phead->prev = phead;
return phead;
}
}
void ListPrint(LTNode* phead)
{
assert(phead);
//从头节点的下一个开始遍历
LTNode* cur = phead->next;
//找到头节点后停止遍历
while (cur != phead)
{
printf("%d ", cur->data);
cur = cur->next;
}
printf("\n");
}
LTNode* newnode(LTDateType x)
{
LTNode* newNode = (LTNode*)malloc(sizeof(LTNode));
if (newNode != NULL)
{
\\存入数据
newNode->data = x;
newNode->prev = newNode->next = NULL;
return newNode;
}
}
void ListPushBack(LTNode* phead, LTDateType x)
{
assert(phead);
LTNode* newNode = newnode(x);
LTNode* tail = phead->prev;
if (newNode != NULL)
{
\\链接前后两个节点,形成双向的链表。
tail->next = newNode;
newNode->prev = tail;
\\链接为节点和头节点,形成循环结构。
newNode->next = phead;
phead->prev = newNode;
}
}
void ListPopBack(LTNode* phead)
{
\\判断是否还有数据可以删除
assert(phead->next != phead);
\\找到尾节点
LTNode* cur = phead->prev;
\\将我们的尾节点指向的prev指向我们的头节点。
cur->prev->next = phead;
\\phead又之指向回去,形成循环。
phead->prev = cur->prev;
\\最后释放空间
free(cur);
cur = NULL;
}
void ListPushFront(LTNode* phead, LTDateType x)
{
assert(phead);
LTNode* newNode = newnode(x);
\\记录phead指向的下一个节点,为后面链接做好准备。
LTNode* Next = phead->next;
\\链接头节点和我们malloc出来的就节点形成双向
phead->next = newNode;
newNode->prev = phead;
\\链接malloc出来的节点和Next将链表整体链接起来。
newNode->next = Next;
Next->prev = newNode;
}
void ListPopFront(LTNode* phead)
{
assert(phead);
\\判断是否还有数据
assert(phead->next != phead);
LTNode* next = phead->next;
LTNode* nextNext = next->next;
\\释放空间
free(next);
\\链接phead和nextNext
phead->next = nextNext;
nextNext->prev = phead;
}
LTNode* ListFind(LTNode* phead, LTDateType x)
{
assert(phead);
LTNode* cur = phead->next;
while (cur != phead)
{
if (cur->data == x)
{
return cur;
}
cur = cur->next;
}
\\没找到返回NULL
return NULL;
}
LTNode* ListTnsert(LTNode* pos, LTDateType x)
{
assert(pos);
\\pos前一个节点
LTNode* posPrev = pos->prev;
\\malloc一块节点
LTNode* newNode = newnode(x);
\\链接
posPrev->next = newNode;
newNode->prev = posPrev;
newNode->next = pos;
pos->prev = newNode;
}
LTNode* ListErase(LTNode* pos)
{
assert(pos);
\\找到pos前一个节点
LTNode* posPrev = pos->prev;
\\找到pos后一个节点
LTNode* posNext = pos->next;
\\链接
posPrev->next = posNext;
posNext->prev = posPrev;
\\释放空间
free(pos);
pos = NULL;
}
void ListDestroy(LTNode* phead)
{
assert(phead);
LTNode* cur = phead->next;
while (cur != phead)
{
LTNode* next = cur->next;
free(cur);
cur = next;
}
}
如果我们仔细点观察的话,我们会发现我们的尾插和头插都是可以用 (给定任意位置插入)来代替的。
而我的尾删和头删都是可以用 (给定任意位置删除)来代替的。
你这里看似我们的newnode是子phead的后面,但是如果我们遍历的话还是从phead->next开始的,到phead停止的,而我们遍历的时候newnode还是最后一个遍历的,这里其实就是画的像这样,但是如果我们换个角度看(把newnode放在最后面)就很明显了。
而我们的头插其实就是在phead-next地方插入。
这个就相对来计较好理解,直接头插。
所以我们的尾插和头插就可改成这个样子:
尾插
void ListPushBack(LTNode* phead, LTDateType x)
{
assert(phead);
ListTnsert(phead, x);
}
头插
void ListPushFront(LTNode* phead, LTDateType x)
{
assert(phead);
ListTnsert(phead->next, x);
}
尾删
void ListPopBack(LTNode* phead)
{
assert(phead->next != phead);
ListErase(phead->prev);
}
头删
void ListPopFront(LTNode* phead)
{
assert(phead);
assert(phead->next != phead);
ListErase(phead->next);
}
#define _CRT_SECURE_NO_WARNINGS 1
#pragma once
#include
#include
#include
typedef int LTDateType;
typedef struct ListNode
{
LTDateType data;
struct ListNode* next;
struct ListNode* prev;
}LTNode;
//初始化
LTNode* ListInit();
//链表打印
void ListPrint(LTNode* phead);
//尾插
void ListPushBack(LTNode* phead, LTDateType x);
//尾删
void ListPopBack(LTNode* phead);
//头插
void ListPushFront(LTNode* phead, LTDateType x);
//头删
void ListPopFront(LTNode* phead);
//查找
LTNode* ListFind(LTNode* phead,LTDateType x);
//给定位置插入
LTNode* ListTnsert(LTNode* pos, LTDateType x);
//给定位置删除
LTNode* ListErase(LTNode* pos);
//释放空间
void ListDestroy(LTNode* phead);
#define _CRT_SECURE_NO_WARNINGS 1
#include "DList.h"
LTNode* ListInit()
{
//设置哨兵为
LTNode* phead = (LTNode*)malloc(sizeof(LTNode));
if (phead != NULL)
{
phead->next = phead;
phead->prev = phead;
return phead;
}
}
void ListPrint(LTNode* phead)
{
assert(phead);
LTNode* cur = phead->next;
while (cur != phead)
{
printf("%d ", cur->data);
cur = cur->next;
}
printf("\n");
}
LTNode* newnode(LTDateType x)
{
LTNode* newNode = (LTNode*)malloc(sizeof(LTNode));
if (newNode != NULL)
{
newNode->data = x;
newNode->prev = newNode->next = NULL;
return newNode;
}
}
void ListPushBack(LTNode* phead, LTDateType x)
{
assert(phead);
//LTNode* newNode = (LTNode*)malloc(sizeof(LTNode));
//LTNode* tail = phead->prev;
//if (newNode != NULL)
//{
// newNode->data = x;
// tail->next = newNode;
// newNode->prev = tail;
//
// newNode->next = phead;
// phead->prev = newNode;
//}
ListTnsert(phead, x);
}
void ListPopBack(LTNode* phead)
{
assert(phead->next != phead);
//LTNode* cur = phead->prev;
//cur->prev->next = phead;
//phead->prev = cur->prev;
//free(cur);
//cur = NULL;
ListErase(phead->prev);
}
void ListPushFront(LTNode* phead, LTDateType x)
{
//assert(phead);
//LTNode* newNode = newnode(x);
//LTNode* Next = phead->next;
//phead->next = newNode;
//newNode->prev = phead;
//newNode->next = Next;
//Next->prev = newNode;
ListTnsert(phead->next, x);
}
void ListPopFront(LTNode* phead)
{
assert(phead);
assert(phead->next != phead);
//LTNode* next = phead->next;
//LTNode* nextNext = next->next;
//free(next);
//phead->next = nextNext;
//nextNext->prev = phead;
ListErase(phead->next);
}
LTNode* ListFind(LTNode* phead, LTDateType x)
{
assert(phead);
LTNode* cur = phead->next;
while (cur != phead)
{
if (cur->data == x)
{
return cur;
}
cur = cur->next;
}
return NULL;
}
//在pos位置之前插入
LTNode* ListTnsert(LTNode* pos, LTDateType x)
{
assert(pos);
LTNode* posPrev = pos->prev;
LTNode* newNode = newnode(x);
posPrev->next = newNode;
newNode->prev = posPrev;
newNode->next = pos;
pos->prev = newNode;
}
LTNode* ListErase(LTNode* pos)
{
assert(pos);
LTNode* posPrev = pos->prev;
LTNode* posNext = pos->next;
posPrev->next = posNext;
posNext->prev = posPrev;
free(pos);
pos = NULL;
}
void ListDestroy(LTNode* phead)
{
assert(phead);
LTNode* cur = phead->next;
while (cur != phead)
{
LTNode* next = cur->next;
free(cur);
cur = next;
}
}
#define _CRT_SECURE_NO_WARNINGS 1
#include
#include "DList.h"
void textList1()
{
//初始化
LTNode* plist = ListInit();
ListPushBack(plist, 1);
ListPushBack(plist, 2);
ListPushBack(plist, 3);
ListPushBack(plist, 4);
ListPopBack(plist);
ListPopBack(plist);
//ListPopBack(plist);
//ListPopBack(plist);
//ListPopBack(plist);
ListPrint(plist);
}
void textList2()
{
LTNode* plist = ListInit();
ListPushFront(plist, 6);
ListPushFront(plist, 7);
ListPushFront(plist, 8);
ListPushFront(plist, 9);
ListPopFront(plist);
ListPopFront(plist);
//ListPopFront(plist);
//ListPopFront(plist);
ListPrint(plist);
}
void textList3()
{
LTNode* plist = ListInit();
ListPushFront(plist, 6);
ListPushFront(plist, 7);
ListPushFront(plist, 8);
ListPushFront(plist, 9);
LTNode* pos=ListFind(plist, 9);
ListTnsert(pos, 60);
ListPrint(plist);
ListDestroy(plist);
plist = NULL;
}
int main()
{
textList1();
textList2();
//textList3();
return 0;
}