数据结构算法之《双向链表的ADMFS)全部操作

一、【头文件】:

#pragma once
#ifdef __cplusplus
extern "C"
{
#endif


#include <stdio.h>
#include <stdlib.h>


    typedef struct Node
    {
        int Data;
        struct Node* P_Pre;
        struct Node* P_Next;
    }Node;

    typedef struct DoubleList
    {
        Node* P_Head;
        Node* P_Tail;
    }DoubleList;

    //初始化节点
    void InitNode(Node* P_Node, int Data);
    //正向显示链表
    void Show(DoubleList List);
    //反向显示链表
    void ShowRev(DoubleList List);
    //头部插入
    void PushHead(DoubleList* P_List, int Data);
    //尾部插入
    void PushBack(DoubleList* P_List, int Data);
    //查找节点(从头到尾)
    Node* FindNode(DoubleList List, int Obj);
    //查找节点(从尾到头)
    Node* FindNodeRev(DoubleList List, int Obj);
    //指定位置插入节点
    void InsertNode(DoubleList* List, int Rear, int InsData);
    //指定位置插入节点
    void InsertNode(DoubleList* P_List, int Rear, int InsData);
    //删除指定节点
    void DeleteNode(DoubleList* P_List, int DelData);
    //修改指定节点
    void Modification(DoubleList List, int OldData, int NewData);
    //销毁链表
    void Destroy(DoubleList* P_List);
    //快速排序
    void QuickSort(Node* P_Begin, Node* P_End);
    //分段(辅助快速排序)
    Node*  Segmentation(Node* P_Begin, Node* P_End);
    //数据交换(辅助排序)
    void Swap(Node* Pa, Node* Pb);
#ifdef __cplusplus
}
#endif
 

二、【源文件】:

#include "stdafx.h"
#include "dulheader.h"


//初始化节点
void InitNode(Node* P_Node, int Data)
{
    P_Node->P_Next = P_Node->P_Pre = NULL;
    P_Node->Data = Data;
}

//正向显示链表
void Show(DoubleList List)
{
    printf("%8s%10s%15s\n", "前驱", "后继", "值");
    while (NULL != List.P_Head)
    {
        printf("%p\t%p\t%d\n", List.P_Head->P_Pre, List.P_Head->P_Next, List.P_Head->Data);
        List.P_Head = List.P_Head->P_Next;
    }
    //换行
    puts("");
}

//反向显示链表
void ShowRev(DoubleList List)
{
    printf("%8s%10s%15s\n", "前驱", "后继", "值");
    while (NULL != List.P_Tail)
    {
        printf("%p\t%p\t%d\n", List.P_Tail->P_Pre, List.P_Tail->P_Next, List.P_Tail->Data);
        List.P_Tail = List.P_Tail->P_Pre;
    }
    //换行
    puts("");
}

//头部插入
void PushHead(DoubleList* P_List, int Data)
{
    //创建一个新节点
    Node* P_New = (Node*)malloc(sizeof(Node));
    //初始化新节点
    InitNode(P_New, Data);


    if (P_List->P_Head == NULL&&P_List->P_Tail == NULL)
    {
        //没有节点的情况

        //头指针和尾指针一样
        P_List->P_Head = P_List->P_Tail = P_New;
    }
    else
    {
        //有节点的情况

        //只针对头指针

        //改变头节点的前驱
        P_List->P_Head->P_Pre = P_New;
        //改变新节点的后继
        P_New->P_Next = P_List->P_Head;
        //重新定义头指针
        P_List->P_Head = P_New;
    }


}

//尾部插入
void PushBack(DoubleList* P_List, int Data)
{
    //创建一个新节点
    Node* P_New = (Node*)malloc(sizeof(Node));
    //初始化新节点
    InitNode(P_New, Data);


    if (P_List->P_Head == NULL && P_List->P_Tail == NULL)
    {
        //没有节点的情况

        //头指针和尾指针一样
        P_List->P_Head = P_List->P_Tail = P_New;
    }
    else
    {
        //有节点的情况

        //只针对尾指针

        //改变尾节点后继
        P_List->P_Tail->P_Next = P_New;
        //改变新节点的前驱
        P_New->P_Pre = P_List->P_Tail;
        //重新的定义尾指针
        P_List->P_Tail = P_New;
    }
}

//查找节点(从头到尾)
Node* FindNode(DoubleList List, int Obj)
{
    //穷举
    while (NULL != List.P_Head)
    {
        if (List.P_Head->Data == Obj)
        {
            return List.P_Head;
        }
        List.P_Head = List.P_Head->P_Next;
    }
    return NULL;
}

//查找节点(从尾到头)
Node* FindNodeRev(DoubleList List, int Obj)
{
    //穷举
    while (NULL != List.P_Tail)
    {
        if (List.P_Tail->Data == Obj)
        {
            return List.P_Tail;
        }
        List.P_Tail = List.P_Tail->P_Pre;
    }
    return NULL;
}

//指定位置插入节点
void InsertNode(DoubleList* P_List, int Rear, int InsData)
{
    if (NULL == P_List->P_Head&&NULL == P_List->P_Tail)
    {
        //如果没有节点,那还插个毛啊。
        return;
    }
    else
    {
        Node* P_Res = FindNode(*P_List, Rear);
        if (NULL != P_Res)
        {
            //如果找到了就创建一个节点
            Node* P_New = (Node*)malloc(sizeof(Node));
            InitNode(P_New, InsData);

            if (P_Res == P_List->P_Tail)
            {
                //如果“P_Res”等于尾指针
                P_New->P_Pre = P_List->P_Tail;
                P_List->P_Tail->P_Next = P_New;
            }
            else
            {
                P_New->P_Pre = P_Res;
                P_New->P_Next = P_Res->P_Next;
                P_Res->P_Next = P_New;
            }
        }

    }
}

//删除指定节点
void DeleteNode(DoubleList* P_List, int DelData)
{
    if (NULL == P_List->P_Head&&NULL == P_List->P_Tail)
    {
        //没有节点的情况
        return;
    }
    else
    {
        Node* P_Res = FindNode(*P_List, DelData);
        if (NULL != P_Res)
        {
            if (P_Res == P_List->P_Head)
            {
                //若“P_Res”等于头结点
                P_List->P_Head = P_List->P_Head->P_Next;
                free(P_Res);
                P_Res = NULL;
            }
            else if (P_Res != P_List->P_Head&&P_Res != P_List->P_Tail)
            {
                //若“P_Res”等于头尾区间内的节点
                P_Res->P_Pre->P_Next = P_Res->P_Next;
                P_Res->P_Next->P_Pre = P_Res->P_Pre;
                free(P_Res);
                P_Res = NULL;
            }
            else
            {
                //若“P_Res”等于尾结点
                P_List->P_Tail = P_List->P_Tail->P_Pre;
                P_List->P_Tail->P_Next = NULL;
                free(P_Res);
                P_Res = NULL;
            }
        }
    }
}

//修改指定节点
void Modification(DoubleList List, int OldData, int NewData)
{
    if (NULL == (List.P_Head) && NULL == (List.P_Tail))
    {
        return;
    }
    else
    {
        Node* P_Res = FindNode(List, OldData);
        if (NULL != P_Res)
        {
            P_Res->Data = NewData;
        }
    }
}

//销毁链表
void Destroy(DoubleList* P_List)
{
    while (NULL != P_List->P_Head)
    {
        DeleteNode(P_List, P_List->P_Head->Data);
        P_List->P_Head = P_List->P_Head->P_Next;
    }
}

//快速排序
void QuickSort(Node* P_Begin, Node* P_End)
{
    if (P_Begin != P_End)
    {
        Node* Pi = Segmentation(P_Begin, P_End);
        QuickSort(P_Begin, Pi);
        QuickSort(Pi->P_Next, P_End);
    }
}
//分段(辅助快速排序)
Node*  Segmentation(Node* P_Begin, Node* P_End)
{
    int Key = P_Begin->Data;
    Node* Pi = P_Begin;
    for (Node* Pj = Pi->P_Next; Pj!= NULL; Pj = Pj->P_Next)
    {
        if (Key < Pj->Data)
        {
            Pi = Pi->P_Next;
            Swap(Pi, Pj);
        }
    }

    Swap(P_Begin, Pi);
    return Pi;
}

//数据交换(辅助排序)
void Swap(Node* Pa, Node* Pb)
{
    int Temp = Pa->Data;
    Pa->Data = Pb->Data;
    Pb->Data = Temp;
}
 

三、【主函数】

// demos.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"

#include "dulheader.h"
#include <time.h>

int _tmain(int argc, _TCHAR* argv[])
{
    printf("\n程序选择效果如下:\n");
    /*******************头部插入*******************/
#if 0
    DoubleList List = { 0 };

    for (int i = 0; i < 10; i++)
    {
        PushHead(&List, i);
    }

    Show(List);
    ShowRev(List);
#endif 

    /*******************尾部插入*******************/
#if 0
    DoubleList List = { 0 };

    for (int i = 0; i < 10; i++)
    {
        PushBack(&List, i);
    }

    Show(List);
    ShowRev(List);
#endif 


    /*******************正向查找节点*******************/
#if 0
    DoubleList List = { 0 };

    for (int i = 0; i < 10; i++)
    {
        PushBack(&List, i);
    }

    Show(List);
    ShowRev(List);

    Node* P_Res[10] = { 0 };

    for (int i = 0; i < 10; i++)
    {
        if (NULL != FindNode(List, i))
        {
            P_Res[i] = FindNode(List, i);
        }
    }
    for (int i = 0; i < 10; i++)
    {
        NULL != P_Res[i] ? printf("%d\n", P_Res[i]->Data) : 0;
    }

#endif 


    /*******************反向查找节点*******************/
#if 0
    DoubleList List = { 0 };

    for (int i = 0; i < 10; i++)
    {
        PushBack(&List, i);
    }

    Show(List);
    ShowRev(List);

    Node* P_Res[10] = { 0 };

    for (int i = 0; i < 10; i++)
    {
        if (NULL != FindNode(List, i))
        {
            P_Res[i] = FindNodeRev(List, i);
        }
    }
    for (int i = 0; i < 10; i++)
    {
        NULL != P_Res[i] ? printf("%d\n", P_Res[i]->Data) : 0;
    }

#endif 


    /*******************指定位置插入节点*******************/
#if 0
    DoubleList List = { 0 };

    for (int i = 0; i < 10; i++)
    {
        PushBack(&List, i);
    }

    Show(List);
    InsertNode(&List, 0, 100);
    InsertNode(&List, 5, 100);
    InsertNode(&List, 9, 100);
    InsertNode(&List, 179, 100);
    Show(List);

#endif 

    /*******************删除指定节点*******************/
#if 0
    DoubleList List = { 0 };

    for (int i = 0; i < 10; i++)
    {
        PushBack(&List, i);
    }


    Show(List);
    DeleteNode(&List, 0);
    DeleteNode(&List, 5);
    DeleteNode(&List, 9);
    DeleteNode(List, 199, 2018);
    Show(List);

#endif 

    /*******************修改指定节点*******************/
#if 0
    DoubleList List = { 0 };

    for (int i = 0; i < 10; i++)
    {
        PushBack(&List, i);
    }


    Show(List);
    Modification(List, 0, 2018);
    Modification(List, 5, 2018);
    Modification(List, 9, 2018);
    Modification(List, 199, 2018);
    Show(List);

#endif 


    /*******************销毁链表*******************/
#if 0
    DoubleList List = { 0 };

    for (int i = 0; i < 10; i++)
    {
        PushBack(&List, i);
    }


    Show(List);
    Destroy(&List);
    Show(List);

#endif 


    /*******************快速排序*******************/
#if 1
    DoubleList List = { 0 };
    srand((unsigned int)time(NULL));
    for (int i = 0; i < 10; i++)
    {
        PushBack(&List, rand() % 100);
    }

    Show(List);
    QuickSort(List.P_Head, NULL);

    Show(List);

#endif 
    system("pause");

    return 0;
}

四、【程序运行效果】