双向循环链表:链表创建、节点插入、链表打印、节点长度计算、链表清空、链表销毁

/* 双向循环链表:在单向循环链表的基础上修改
    初始化
    前向插入
    后向插入
    打印
    链表长度
    清空
    销毁
*/
#include <stdio.h>
#include <stdlib.h>

#define itemType int

typedef struct node
{
    itemType data;
    struct node *pPrev;
    struct node *pNext;
}Node;

/* 创建Head节点: 节点的pNext为NULL */
int initList(Node **ppN)
{
    if (NULL == ppN)
    {
        printf("pHeadNode point address NULL\n");
        return -1;
    }
    
    Node *pNewNode = (Node *)malloc(sizeof(Node));
    if (NULL == pNewNode)
    {
        printf("initList fail\n");
        return -1;
    }

    printf("pNewNode address: %p\n", pNewNode);
    pNewNode->pPrev = pNewNode;
    pNewNode->pNext = pNewNode;
    pNewNode->data = 0;

    *ppN = pNewNode;
    
    return 0;
}

/* 前向插入一个节点 */
int insertListHead(Node *pN, itemType data)
{
    if (NULL == pN)
    {
        printf("pHeadNode NULL\n");
        return -1;
    }
    
    Node *pNewNode = (Node *)malloc(sizeof(Node));
    if (NULL == pNewNode)
    {
        printf("insertListHead fail\n");
        return -1;
    }
    
    printf("pNewNode address: %p\n", pNewNode);
    pNewNode->pNext = NULL;
    pNewNode->pPrev = NULL;
    pNewNode->data = data;

    pNewNode->pNext = pN->pNext;
    pNewNode->pPrev = pN;
    pN->pNext->pPrev = pNewNode;
    pN->pNext = pNewNode;

    return 0;
}

/* 后向插入一个节点 */
int insertListTail(Node *pN, itemType data)
{
    if (NULL == pN)
    {
        printf("pHeadNode NULL\n");
        return -1;
    }

    Node *pNewNode = (Node *)malloc(sizeof(Node));
    Node *pHeadNode = NULL;
    if (NULL == pNewNode)
    {
        printf("insertListTail fail\n");
        return -1;
    }
    
    printf("pNewNode address: %p\n", pNewNode);
    pNewNode->pPrev = NULL;
    pNewNode->pNext = NULL;
    pNewNode->data = data;
    
    pHeadNode = pN;
    /* 查找最后一个节点 */
    while(pHeadNode != pN->pNext)
    {
        pN = pN->pNext;
    }

    pNewNode->pNext = pN->pNext;
    pNewNode->pPrev = pN;
    pN->pNext->pPrev = pNewNode;
    pN->pNext = pNewNode;

    return 0;
}

/* 链表打印 */
int printList(Node *pN)
{
    Node *pHeadNode = NULL;

    if (NULL == pN)
    {
        printf("printList is not exist\n");
        return -1;
    }
    
    if (NULL == pN->pNext)
    {
        printf("printList is NULL\n");
        return -1;
    }

    pHeadNode = pN;
    do {
        printf("Node address: %p, Node value: %3d, Node Next: %p\n", pN, pN->data, pN->pNext);
        pN = pN->pNext;
    }while(pHeadNode != pN);

    return 0;
}

/* 链表长度 */
int listLength(Node *pN)
{
    int len = 0;
    Node *pHeadNode = NULL;

    if (NULL == pN)
    {
        printf("listLength NULL\n");
        return -1;
    }
    
    pHeadNode = pN;
    while(pHeadNode != pN->pNext)
    {
        len++;
        pN = pN->pNext;
    }
    
    return len;
}

/* 清空链表:保留Head节点,其它全部资源 释放 */
int emptyList(Node *pN)
{
    Node *pHeadNode = NULL;

    if (NULL == pN)
    {
        printf("emptyList is NULL\n");
        return -1;
    }

    pHeadNode = pN;    
    while (pHeadNode != pN->pNext)
    {
        pN->pNext = pN->pNext->pNext;
        
        free(pN->pNext->pPrev);
    }
    pHeadNode->pNext = pHeadNode;
    pHeadNode->pPrev = pHeadNode;

    return 0;
}

/* 销毁链表:释放所有节点,包括Head节点 */
int destoryList(Node **pN)
{
    emptyList(*pN);
    free(*pN);
    *pN = NULL;

    return 0;    
}

/* 测试入口 */
int main(void)
{
    Node *pHeadNode = NULL;
    initList(&pHeadNode);

    for (int i=0; i<20; i++)
    {
        insertListHead(pHeadNode, i+1);
        insertListTail(pHeadNode, i+101);
    }

    printf("listLength: %d\n", listLength(pHeadNode));
    printList(pHeadNode);

    emptyList(pHeadNode);
    destoryList(&pHeadNode);

    printList(pHeadNode);

    return 0;
}

posted @ 2018-11-19 23:08  thinking......  阅读(262)  评论(0编辑  收藏  举报