看:
#include<stdio.h>
#include<stdlib.h>
typedef int LTDataType;
typedef struct ListNode
{
struct ListNode* prev;
struct ListNode* next;
LTDataType data;
}ListNode;
ListNode* BuyListNode(LTDataType x)
{
ListNode* NewNode = (ListNode*)malloc(sizeof(ListNode));
NewNode->prev = NULL;
NewNode->next = NULL;
NewNode->data = x;
return NewNode;
}
ListInit(ListNode** pphead)
{
*pphead = BuyListNode(0);
(*pphead)->prev = *pphead;
(*pphead)->next = *pphead;
}
void ListPrint(ListNode* phead)
{
ListNode* cur = phead->next;
while (cur != phead)
{
printf("%d ", cur->data);
cur = cur->next;
}
printf("\n\n");
}
void ListPushBack(ListNode* phead, LTDataType x)
{
ListNode* tail=phead->prev;
ListNode* newnode = BuyListNode(x);
tail->next = newnode;
newnode->prev = tail;
newnode->next = phead;
phead->prev = newnode;
}
void ListPopBack(ListNode* phead)
{
ListNode* tail = phead->prev;
ListNode* newtail = tail->prev;
free(tail);
newtail->next = phead;
phead->prev = newtail;
}
void ListPushFront(ListNode* phead, LTDataType x)
{
ListNode* FristNode = phead->next;
ListNode* newnode = BuyListNode(x);
phead->next = newnode;
newnode->prev = phead;
newnode->next = FristNode;
FristNode->prev = newnode;
}
void ListPopFront(ListNode* phead)
{
assert(phead->next!=phead);
ListNode* FristNode = phead->next;
ListNode* NewFristNode = FristNode->next;
free(FristNode);
phead->next = NewFristNode;
NewFristNode->prev = phead;
}
void ListTest()
{
ListNode* phead = NULL;
ListInit(&phead);
printf("尾插1,2,3,4,5,6: \n");
ListPushBack(phead,1);
ListPushBack(phead,2);
ListPushBack(phead,3);
ListPushBack(phead,4);
ListPushBack(phead,5);
ListPushBack(phead,6);
ListPrint(phead);
printf("尾删四个数据: \n");
ListPopBack(phead);
ListPopBack(phead);
ListPopBack(phead);
ListPopBack(phead);
ListPrint(phead);
printf("头插9,8,7,6: \n");
ListPushFront(phead, 9);
ListPushFront(phead, 8);
ListPushFront(phead, 7);
ListPushFront(phead, 6);
ListPrint(phead);
printf("尾删三个数据: \n");
ListPopFront(phead);
ListPopFront(phead);
ListPopFront(phead);
ListPrint(phead);
}
int main()
{
ListTest();
return 0;
}
注意:双链表的插入(头插和尾插)操作中无需判断链表是否为空(即除了头节点外是否存在结点),这一特点使得其插入操作变得简单许多; 具体原因就看着代码捋一遍就明白了;
|