带头结点的双向循环链表操作集 (25 分)

本题要求实现一个带头结点的双向循环链表操作集。

函数接口定义:

typedef int dataType;

typedef struct _node
{
    dataType data;
    struct _node *prev;//指向前驱的指针
    struct _node *next;//指向后继的指针
}node;

typedef node* List;

List create_list();//创建一个空的循环链表,返回指向头节点的指针。
void insert(List L, dataType x);//用尾插法向链表L中插入数据域等于x的结点
bool is_empty(List L);//如果链表为空,则返回true,否则返回false。
void traverse(List L);//顺序遍历链表L。输出所有结点的数据域。如果链表为空则输出NULL
void traverse_back(List L);//逆序遍历链表L。输出所有结点的数据域。如果链表为空则输出NULL
node* search(List L, dataType x);//返回第1个指向数据域等于x的结点的指针。如果没有则返回NULL。
void delete_node(List L, node* p);//删除指针p指向的结点。调用者保证p是合法的。
void remove_node(List L, dataType x);//删除链表L中所有数据域等于x的结点
void make_empty(List L);//使链表L成为一个空链表
void destroy_list(List L);//销毁链表L

裁判测试程序样例:

#include 
#include 
#include 

typedef int dataType;

typedef struct _node
{
    dataType data;
    struct _node *prev;//指向前驱的指针
    struct _node *next;//指向后继的指针
}node;

typedef node* List;

List create_list();//创建一个空的循环链表,返回指向头节点的指针。
void insert(List L, dataType x);//用尾插法向链表L中插入数据域等于x的结点
bool is_empty(List L);//如果链表为空,则返回true,否则返回false。
void traverse(List L);//顺序遍历链表L。输出所有结点的数据域。如果链表为空则输出NULL
void traverse_back(List L);//逆序遍历链表L。输出所有结点的数据域。如果链表为空则输出NULL
node* search(List L, dataType x);//返回第1个指向数据域等于x的结点的指针。如果没有则返回NULL。
void delete_node(List L, node* p);//删除指针p指向的结点。调用者保证p是合法的。
void remove_node(List L, dataType x);//删除链表L中所有数据域等于x的结点
void make_empty(List L);//使链表L成为一个空链表
void destroy_list(List L);//销毁链表L

int main()
{
    int x;
    List mylist = create_list();
    //输入一系列正整数,输入0表示输入结束
    //用尾插法插入链表
    scanf("%d", &x);
    while (x != 0)
    {
        insert(mylist, x);
        scanf("%d", &x);
    }
    //顺序遍历链表
    traverse(mylist);
    //逆序遍历链表
    traverse_back(mylist);
    //输入要删除的结点数据域
    scanf("%d", &x);
    node *p = search(mylist, x);
    if (p != NULL)
    {
        delete_node(mylist, p);
    }
    //顺序遍历链表
    traverse(mylist);
    //逆序遍历链表
    traverse_back(mylist);
    //输入要删除的结点数据域
    scanf("%d", &x);
    remove_node(mylist, x);
    //顺序遍历链表
    traverse(mylist);
    //逆序遍历链表
    traverse_back(mylist);
    //销毁链表
    destroy_list(mylist);
    return 0;
}

/* 请在这里填写答案 */

输入样例:

在这里给出一组输入。例如:

10 20 10 10 20 30 0
20
10

输出样例:

在这里给出相应的输出。例如:

10 20 10 10 20 30 
30 20 10 10 20 10 
10 10 10 20 30 
30 20 10 10 10 
20 30 
30 20 

输入输出样例解释:

程序首先创建一个空的双向循环链表,如下图所示:

带头结点的双向循环链表操作集 (25 分)_第1张图片

输入的第1行是

10 20 10 10 20 30 0

此时程序创建一个带头节点的双向循环链表,如下图所示:

带头结点的双向循环链表操作集 (25 分)_第2张图片

 此时顺序输出

10 20 10 10 20 30

逆序输出

30 20 10 10 20 10

输入的第2行是

20

此时程序删除从头结点向后的第1个数据域等于20的结点,所以链表如下图所示:

带头结点的双向循环链表操作集 (25 分)_第3张图片

 此时顺序输出

10 10 10 20 30

逆序输出

30 20 10 10 10

输入的第3行是

10

此时程序删除链表中所有数据域等于10的结点,所以链表如下图所示:

带头结点的双向循环链表操作集 (25 分)_第4张图片

此时顺序输出

20 30

逆序输出

30 20

List create_list() {
    List head = (List)malloc(sizeof(node));
    head->next = head;
    head->prev = head;
    return head;
}
void insert(List L, dataType x) {
    List p = (List)malloc(sizeof(node));
    List t = L->prev;
    p->data = x;
    p->prev = t;
    p->next = L;
    L->prev = p;
    t->next = p;
}
bool is_empty(List L) {
    if (L->next == L&&L->prev==L) {
        return true;
    }
    else return false;
}
void traverse(List L) {
    List head = L;
    if (L->next == head&&L->prev==head) {
        printf("NULL");
    }
    L = L->next;
    while (L != head) {
        printf("%d ", L->data);
        L = L->next;
    }
    printf("\n");
}
void traverse_back(List L) {
    List head = L;
    if (L->next == head && L->prev == head) {
        printf("NULL");
    }
    L = L->prev;
    while (L != head) {
        printf("%d ", L->data);
        L = L->prev;
    }
    printf("\n");
}
node* search(List L, dataType x) {
    List head = L;
    if (L->next == head && L->prev == head) {
        return NULL;
    }
    L = L->next;
    while (L->data != x) {
        L = L->next;
        if (L == head) {
            return NULL;
        }
    }
    return L;
}
void delete_node(List L, node* p) {
    while (L != p) {
        L = L->next;
    }
    L->prev->next = L->next;
    L->next->prev = L->prev;
    free(L);
}
void remove_node(List L, dataType x) {
    List t = L;
    List r;
    int e;
    t = t->next;
    r = t->next;
    while (t != L) {
        if (t->data == x) {
            t->prev->next = t->next;
            t->next->prev = t->prev;
            e = t->data;
            free(t);     
        }
        t = r;
        r = r->next;
    }
}
void make_empty(List L) {
    List head = L;
    L = L->next;
    List t = L;
    while (L != head) {
        L = L->next;
        free(t);
        t = L;
    }
    head->next = head;
    head->prev = head;
}
void destroy_list(List L) {
    List head = L;
    L = L->next;
    List t = L;
    while (L != head) {
        L = L->next;
        free(t);
        t = L;   
    }
    free(head);
}

 

你可能感兴趣的:(链表,链表,数据结构,c语言,算法)