双向循环链表基本操作

双向循环链表

网上弄来的代码,可以说很优秀了。

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <ctype.h>
#define LIST_ELEM_TYPE      int    /*链表元素数据类型*/
LIST_ELEM_TYPE  largest=1 ;
/*链表节点类型*/
typedef struct Node {
    LIST_ELEM_TYPE  Data;
    struct Node   * Prior;
    struct Node   * Next;
} Node;


/*双向循环链表类型*/
typedef struct List {
    Node  * Head;
    int     Length;  
} List;

/*创建新的链表*/
List * CreateList(void) {
    List * list     = (List *) calloc(1, sizeof(List));

    list->Head      = NULL;
    list->Length    = 0;
    return (list);
}


/*创建值为value的新节点*/
Node * CreateNode(LIST_ELEM_TYPE value) {
    Node * node = (Node *) calloc(1, sizeof(Node));

    node->Data  = value;
    node->Prior = NULL;
    node->Next  = NULL;
    return (node);
}


/*在链表结尾附加节点*/
int AppendElement(List * list, LIST_ELEM_TYPE value) {
    if (0 == list->Length) {                    /*若链表为空,则新节点成为第一个节点*/
        list->Head          = CreateNode(value);
        list->Head->Next    = list->Head;
        list->Head->Prior   = list->Head;
        list->Length        = 1;
    }
    else {
        Node  * node            = CreateNode(value);

        node->Next              = list->Head;
        node->Prior             = list->Head->Prior;
        list->Head->Prior->Next = node;
        list->Head->Prior       = node;
        ++(list->Length);
    }
    return (0);
}


/*在链表中pos位置处插入元素value*/
int InsertElement(List * list, int pos, LIST_ELEM_TYPE value) {
    if (((1 <= pos) && (pos <= (list->Length + 1))) ==0) {
        return (2);
    }
    else if (0 == list->Length) {
        list->Head          = CreateNode(value);
        list->Head->Next    = list->Head;
        list->Head->Prior   = list->Head;
        list->Length        = 1;
    }
    else {
        Node  * newNode  = CreateNode(value);
        Node  * node     = list->Head;
        int     cnt;

        for (cnt = 1; cnt < pos; cnt++) {
            node = node->Next;
        }
        newNode->Next       = node;
        newNode->Prior      = node->Prior;
        node->Prior->Next   = newNode;
        node->Prior         = newNode;          /*插入新节点*/

        if (1 == pos) {
            list->Head = newNode;
        }                            /*若新节点为一号节点,则更新链表头指针*/
        ++(list->Length);
    }
    return (0);
}


/*删除链表并对占用的存储空间进行回收*/
int DisposeList(List * list)  {
    if (NULL == list) {
        return (0);      /*若链表不存在,则直接返回*/
    }
    if (0 == list->Length) {
        free(list);
    }
    else {
        Node * head = list->Head;
        Node * node = head;
        Node * todo;
        do {
            todo = node->Next;
            free(node);
            node = todo;
        } while (head != node);     /*遍历链表,并回收各元素的存储空间*/
        free(list);
    }
    return (0);
}


/*将链表重置为空表*/
int ClearList(List * list) {
    if (0 == list->Length) {
        list->Head = NULL;
    }
    else {
        Node  * head = list->Head;
        Node  * node = head;
        Node  * todo;
        do {
            todo = node->Next;
            free(node);
            node = todo;
        } while (head != node);
        list->Head      = NULL;
        list->Length    = 0;
    }
    return (0);
}


/*判断链表是否为空*/
int IsListEmpty(List * list) {
    if (NULL == list) {
        return (1);
    }
    else if (0 == list->Length) {
        return (1);
    }
    else {
        return (0);
    }
}


/*返回链表元素个数*/
int ListLength(List * list) {
    if (NULL == list) {
        return (3);
    }
    else {
        return (list->Length);
    }
}


/*链表中pos位置删除元素,并将数据存于value中*/
int DeleteElement(List * list, int pos, LIST_ELEM_TYPE * value) {
    if (NULL == list) {
        return (3);                    /*判断链表是否存在*/
    }
    else if (((1 <= pos) && (pos <= (list->Length))) ==0) {
        return (2);                     /*判断pos位置是否存在*/
    }
    else {
        Node  * node     = list->Head;
        int     cnt;

        for (cnt = 1; cnt < pos; cnt++) {
            node = node->Next;
        }                                           /*遍历链表,查找第pos个元素*/
        *value = node->Data;
        node->Next->Prior = node->Prior;
        node->Prior->Next = node->Next;
        if (1 == pos) {
            list->Head = node->Next;
        }                                           /*若是第一个元素,则更新链表头指针*/
        free(node);
        if (0 == (--(list->Length))) {
            list->Head = NULL;
        }
        return (0);
    }
}


/*链表中删除第一个值为value的元素*/
int DeleteData(List * list, LIST_ELEM_TYPE value) {
    if (NULL == list) {         
        return (3);                    /*判断链表是否存在*/
    }
    else if (0 == list->Length) {
        return (2);
    }
    else {
        Node  * head = list->Head;
        Node  * node = head;

        do {
            if (value == node->Data) {
                break;
            }
            node = node->Next;
        } while (node != head);                     /*遍历链表,查找值为value的元素*/

        if (value != node->Data) {
            return (4);
        }

        node->Next->Prior = node->Prior;
        node->Prior->Next = node->Next;
        if (list->Head == node) {
            list->Head = node->Next;
        }
        free(node);
        if (0 == (--(list->Length))) {
            list->Head = NULL;
        }
        return (0);
    }
}


/*比较数字a和b的是否相等*/
int NumberCompare(LIST_ELEM_TYPE * a, LIST_ELEM_TYPE * b) {
    if ((*a) == (*b)) {
        return (1);
    }
    else {
        return (0);
    }
}


/*查询链表中第一处与value满足compare()关系的元素位置,结果存放在pos中*/
int LocateElement(List * list, int * pos, LIST_ELEM_TYPE value, int (*compare)(void *, void *)) {
    if (NULL == list) {
        return (3);
    }
    else {
        int     cnt  = 1;
        int     len  = list->Length;
        Node  * head = list->Head;
        Node  * node = head;

        do {
            if ( compare(&value, &(node->Data))==1) {
                break;
            }
            cnt++;
            node = node->Next;
        } while (node != head);
        if (compare(&value, &(node->Data))!=1) {
            return (4);
        }
        else {
            *pos = cnt;
            return (3);
        }
    }
}


/*依次对链表中每个元素调用visit()*/
int TraverseList(List * list, int (*visit)(void *)) {
    if (NULL == list) {
        return (3);                    /*判断链表是否存在*/
    }
    else if (0 == list->Length) {
        return (2);                     /*判断链表是否为空*/
    }
    else {
        Node  * head = list->Head;
        Node  * node = head;

        do {
            if (visit(&(node->Data))!=0) {
                return (6);
            }
            node = node->Next;
        } while (node != head);                     /*遍历链表,对各元素依次进行visit操作*/

        return (0);
    }
}


/*显示数字*/
int DisplayNumber(LIST_ELEM_TYPE * num) {
    printf("%d ", *num);
    return (0);
}


/*累加求和*/
long    sum = 0;
int ComputeSum(LIST_ELEM_TYPE * num) {
    sum += *num;
    return (0);
}


/*记录最大数*/
int RecordLarger(LIST_ELEM_TYPE * num) {
    if (*num > largest) {
        largest = *num;
    }
    return (0);
}


/*对链表中每个元素就地逆置*/
int ReverseList(List * list) {
    if (NULL == list) {
        return (3);            /*若链表不存在*/
    }
    else if (list->Length <= 1) {
        return (0);              /*若链表仅含有一个元素,则无需逆置*/
    }
    else if (list->Length == 2) {
        list->Head = list->Head->Prior;
        return (0);              /*若链表含有两个元素,则将头指针后移即可*/
    }
    else {
        Node  * head = list->Head;
        Node  * tail = list->Head->Prior;
        Node  * node;
        int     i    = 0;
        int     cnt  = (list->Length)/2;
        if (0 == (0x1 & (list->Length))) {
            --cnt;
        }

        list->Head = list->Head->Prior;     /*更新链表头指针位置*/

        head->Next->Prior   = tail;
        tail->Prior->Next   = head;
        head->Prior         = tail->Prior;
        tail->Next          = head->Next;
        head->Next          = tail;
        tail->Prior         = head;         /*交换链表头尾节点指针关系*/

        for (i = 1; i < cnt; i++) {
            node = head;
            head = tail->Next;
            tail = node->Prior;

            head->Next->Prior   = tail;
            head->Prior->Next   = tail;
            tail->Next->Prior   = head;
            tail->Prior->Next   = head;
            node                = head->Next;
            head->Next          = tail->Next;
            tail->Next          = node;
            node                = head->Prior;
            head->Prior         = tail->Prior;
            tail->Prior         = node;     /*交换链表中间非相邻节点指针关系*/
        }

        if (0 == (0x1 & (list->Length))) {  
            node = head;
            head = tail->Next;
            tail = node->Prior;

            tail->Next->Prior   = head;
            head->Prior->Next   = tail;
            head->Next          = tail->Next;
            tail->Prior         = head->Prior;
            head->Prior         = tail;
            tail->Next          = head;     /*交换链表中间相邻节点指针关系*/
        }

        return (0);
    }
}

/*程序功能菜单*/
char * mainMenu [] = {
    "(1)Load The DoubleList",
    "(2)Clear The Doublelist ",
    "(3)Destroy The DoubleList",
    "(4)Get The Length of The DoubleList",
    "(5)Insert A Data",
    "(6)Delete A Data According to the Position",
    "(7)Delete A Data According to the Value",
    "(8)Display All The Data",
    "(9)Get the Max of the Data",
    "(10)Get the average of the Data",
    "(11)Reverse The DoubleList",
    "(12)Exit",
    NULL
};


/*从文件中载入线性表*/
int InputFromFile (char * filename, List * list) {
    LIST_ELEM_TYPE  num;
    int             i = 0;
    FILE * fin = fopen(filename, "a+");

    if (NULL == fin) {
        printf("%s doesn't exist!The Data can't be loaded!\n", filename);
        return (0);
    }
    else {
        while (EOF != fscanf(fin, "%d", &num)) {
            i++;
            InsertElement(list, i, num);
        }
        return (0);
    }
}

int  main(void) {
    int   i;
    int   c;
    List  * list;
    LIST_ELEM_TYPE  num;
    LIST_ELEM_TYPE  num2;
    list = CreateList();
    InputFromFile("DoubleList.dat", list);
    /*TraverseList(list, (int (*)(void *))DisplayNumber);*/
    do {
        i = 0;
        printf("Welcome to the System!\n");
        while (NULL != mainMenu[i]) {
            printf("  %s\n", mainMenu[i]);
            i++;
        }
        printf("Choose the type of Operation:");
        scanf("%d", &c);
        switch (c) {
            /*(1)载入线性表*/
            case  1:
                DisposeList(list);
                list = CreateList();
                if ((InputFromFile("DoubleList.dat",list))==0) {
                    printf("The DoubleList has been loaded,there are %d of data in total.\n", ListLength(list));
                }
                break;

            /*(2)线性表置空*/
            case  2:
                if (NULL == list) {
                    printf("The DoubleList doesn't exist!\n");
                }
                else {
                    ClearList(list);
                    printf("The DoubleList has been cleared!\n");
                }
                break;

            /*(3)销毁线性表*/
            case  3:
                DisposeList(list);
                list = NULL;
                printf("The DoubleList has been destroyed!\n");
                break;

            /*(4)获取线性表长度*/
            case  4:
                if (NULL == list) {
                    printf("The DoubleList doesn't exist!\n");
                }
                else {
                    i = ListLength(list);
                    if (0 == i) {
                        printf("The DoubleList is empty\n");
                    }
                    else {
                        printf("The length of the list is %d\n", i);
                    }
                }
                break;
           /*(5)插入数据元素*/
            case  5:
                if (NULL == list) {
                    printf("The DoubleList doesn't exist\n");
                }
                else {
                    printf("The position of the inserted data:");
                    scanf("%d", &i);
                    printf("The value of the inserted data:");
                    scanf("%d", &num);
                    if (InsertElement(list, i, num)==0) {
                        printf("Successfully inserted\n");
                    }
                    else {
                        printf("Fail to insert!\n");
                    }
                }
                break;

            /*(6)删除位置数据元素*/
            case  6:
                if (NULL == list) {
                    printf("The DoubleList doesn't exist\n");
                }
                else {
                    printf("The position of the deleted data:");
                    scanf("%d", &i);
                    if ( DeleteElement(list, i, &num)==0) {
                        printf("Successfully deleted!\n", num);
                    }
                    else {
                        printf("Fail to delete!\n");
                    }
                }
                break;

            /*(7)删除数值数据元素*/
            case  7:
                if (NULL == list) {
                    printf("The DoubleList doesn't exist\n");
                }
                else {
                    printf("The value of the deleted data:");
                    scanf("%d", &num);
                    if (DeleteData(list, num)==0) {
                        printf("Successfully deleted!\n", num);
                    }
                    else {
                        printf("Fail to delete!\n");
                    }
                }
                break;

            /*(8)显示全部数据元素*/
            case  8:
                if (NULL == list) {
                    printf("The DoubleList doesn't exist!\n");
                }
                else if ( IsListEmpty(list)==1) {
                    printf("The DoubleList is empty!\n");
                }
                else {
                    printf("Display the DoubleList:");
                    TraverseList(list, (int (*)(void *))DisplayNumber);
                    printf("\n");
                }
                break;

            /*(9)求最大元素*/
            case  9:
                if (NULL == list) {
                    printf("The DoubleList doesn't exist!\n");
                }
                else if (0 == ListLength(list)) {
                        printf("The DoubleList is empty!\n");
                }
                else {
                    largest =1;
                    TraverseList(list, (int (*)(void *))RecordLarger);
                    printf("The max of the data is:%d\n", largest);
                }
                break;

            /*(10)求所有元素平均值*/
            case  10:
                if (NULL == list) {
                    printf("The DoubleList doesn't exist!\n");
                }
                else if (0 == (i = ListLength(list))) {
                        printf("The DoubleList is empty!\n");
                }
                else {
                    sum = 0;
                    TraverseList(list, (int (*)(void *))ComputeSum);
                    printf("The Length of the list is:%d\n",i);
                    printf("The sum of all the data is %d\n",sum);
                    printf("The average is %f\n",((double)sum)/((double)i));
                }
                break;

            /*(11)就地置逆线性表*/
            case  11:
                if (NULL == list) {
                    printf("The DoubleList doesn't exist!\n");
                }
                else {
                    ReverseList(list);
                    printf("The DoubleList has been reversed\n");
                }
                break;

            /*(12)退出程序*/
            case  12:
                printf("ByeBye!\n");
                break;
            default:
                printf("The operation doesn't exist!\n");
                break;
        }
        getchar();
        getchar();
    } while (c!= 12);
  return (0);
}

猜你喜欢

转载自blog.csdn.net/wcs_152/article/details/78873292