學習不易,需要堅持。
//DList.h
#pragma once
typedef int DLDataType ;
typedef struct DListNode
{
//結點
DLDataType val ;
struct DListNode* next ;
struct DListNode* prev ;
}DListNode ;
typedef struct
{
//雙鏈表類型
DListNode* head ;
}DList ;
//內部接口,申請新結點
DListNode* BuyNode(DLDataType val) ;
//初始化
void DListInit(DList* dlist) ;
//清空
void DListClear(DList* dlist) ;
//銷燬(銷燬後爲無效鏈表,注意與“清空”區分)
void DListDestroy(DList* dlist) ;
//頭插
void DListPushFront(DList* dlist, DLDataType val) ;
//尾插
void DListPushBack(DList* dlist, DLDataType val) ;
//在pos結點前做插入
void DListInsert(DListNode* pos,DLDataType val) ;
//打印
void DListPrintByDList(DList* dlist) ;
//查找並返回某結點的地址
DListNode* DListFind(DList* dlist, DLDataType val) ;
//刪除pos位置的點(非頭)
void DListErase(DListNode* pos) ;
//頭刪
void DListPopFront(DList* dlist) ;
//尾刪
void DListPopBack(DList* dlist) ;
//DList.c
#include "DList.h"
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
//內部接口,申請新結點
DListNode* BuyNode(DLDataType val)
{
DListNode* node = (DListNode*) malloc (sizeof(DListNode)) ;
assert(node) ;
node->val = val ;
node->next = node->prev = NULL ;
return node ;
}
//初始化
void DListInit(DList* dlist)
{
//創建頭結點
DListNode* head = BuyNode(0) ;
assert(head) ;
head->next = head ;
head->prev = head ;
//將頭置於鏈表中
dlist->head = head ;
}
//清空
void DListClear(DList* dlist)
{
DListNode* cur, * next ;
for(cur=dlist->head->next; cur!=dlist->head; cur=next)
{
next = cur->next ;
free(cur) ;
}
dlist->head->next = dlist->head ;
dlist->head->prev = dlist->head ;
}
//銷燬(銷燬後爲無效鏈表,注意與“清空”區分)
void DListDestroy(DList* dlist)
{
DListClear(dlist) ;
free(dlist->head) ;
dlist->head = NULL ; //連頭都沒有了,爲無效鏈表
}
//頭插
void DListPushFront(DList* dlist, DLDataType val)
{
//申請空間
DListNode* node = BuyNode(val) ;
//處理next,prev,4個指針要變
node->prev = dlist->head ;
node->next = dlist->head->next ;
dlist->head->next->prev = node ;
dlist->head->next = node ;
}
//尾插
void DListPushBack(DList* dlist, DLDataType val)
{
//申請空間
DListNode* node = BuyNode(val) ;
node->prev = dlist->head->prev;
node->next = dlist->head ;
dlist->head->prev->next = node ;
dlist->head->prev = node ;
}
//打印
void DListPrintByDList(DList* dlist)
{
DListNode* cur ;
for(cur=dlist->head->next; cur!=dlist->head; cur=cur->next)
{
printf("%d-->",cur->val) ;
}
printf("\n") ;
}
//在pos結點前做插入
void DListInsert(DListNode* pos,DLDataType val)
{
//申請空間
DListNode* node = BuyNode(val) ;
node->next = pos ;
node->prev = pos->prev ;
pos->prev->next = node ;
pos->prev = node ;
}
//查找並返回某結點的地址
DListNode* DListFind(DList* dlist, DLDataType val)
{
DListNode* cur ;
for(cur=dlist->head->next; cur!=dlist->head; cur=cur->next)
{
if(cur->val == val)
{
return cur ;
}
}
return NULL ;
}
//刪除pos位置的點(非頭)
void DListErase(DListNode* pos)
{
pos->prev->next = pos->next ;
pos->next->prev = pos->prev ;
free(pos) ;
}
//頭刪
void DListPopFront(DList* dlist)
{
//斷言,判斷鏈表是否爲空,爲空則不能進行頭刪操作
assert(dlist->head->next != dlist->head) ;
DListErase(dlist->head->next) ;
}
//尾刪
void DListPopBack(DList* dlist)
{
//斷言,判斷鏈表是否爲空,爲空則不能進行頭刪操作
assert(dlist->head->next != dlist->head) ;
DListErase(dlist->head->prev) ;
}
//Main.c
#include "DList.h"
#include <stdio.h>
int main()
{
DList dlist ;
DListNode* pos ;
DListInit(&dlist) ;
printf("頭插:\n") ;
DListPushFront(&dlist, 3) ;
DListPushFront(&dlist, 2) ;
DListPushFront(&dlist, 1) ;
DListPrintByDList(&dlist) ;
printf("\n尾插:\n") ;
DListPushBack(&dlist, 8) ;
DListPushBack(&dlist, 9) ;
DListPushBack(&dlist, 10) ;
DListPrintByDList(&dlist) ;
printf("\n在pos之前插入:\n") ;
pos = DListFind(&dlist, 8) ;
DListInsert(pos,1024) ;
DListPrintByDList(&dlist) ;
printf("\n刪除pos位置的值:\n") ;
DListErase(pos) ;
DListPrintByDList(&dlist) ;
printf("\n頭刪:\n") ;
DListPopFront(&dlist) ;
DListPrintByDList(&dlist) ;
printf("\n尾刪:\n") ;
DListPopBack(&dlist) ;
DListPrintByDList(&dlist) ;
printf("\n") ;
return 0 ;
}
運行結果: