zoukankan      html  css  js  c++  java
  • 循环单链表实现

     
    /********************************************************
    * SClist.h头文件
    /********************************************************/
    #ifndef __SCLIST_H__
    #define __SCLIST_H__
     
    #include<stdio.h>
    #include<malloc.h>
    #include<assert.h>
     
    typedef int ElemType;
     
    typedef struct Node { //定义结构体
        ElemType data;
        struct Node *next;
    }Node,*PNode;
     
    typedef struct List { //定义头尾节点及链表长度
        PNode first;
        PNode last;
        size_t size;
    }List;
     
    void InitSClist(List *list);//初始化循环单链表
    void push_back(List *list, ElemType x);//在循环单链表的末尾插入元素
    void push_front(List *list, ElemType x);//在循环单链表的头部插入元素
    void show_list(List *list);//打印循环单链表
    void pop_back(List *list);//删除循环单链表的最后一个元素
    void pop_front(List *list);//删除循环单链表的第一个元素
    void insert_val(List *list, ElemType val);//将数据元素插入到循环单链表中(要求此时循环单链表中的数据元素顺序排列)
    Node* find(List *list, ElemType x);//查找循环单链表中数据值为x的结点
    int length(List *list);//求循环单链表的长度
    void delete_val(List *list, ElemType x);//按值删除循环单链表中的某个数据元素
    void sort(List *list);//对循环单链表进行排序
    void reverse(List *list);//逆置循环单链表
    void clear(List *list);//清除循环单链表
    void destroy(List *list);//摧毁循环单链表
     
    //优化
    Node* _buynode(ElemType x);//创建结点
     
    #endif
     
     
     
    /********************************************************
    * SClist.c文件
    /********************************************************/
    #include"SClist.h"
     
    /* 创建新节点 */
    Node* _buynode(ElemType x) {
        Node *s = (Node*)malloc(sizeof(Node));
        assert(s != NULL);
        s->data = x;
        s->next = NULL;
        return s;
    }
     
    /* 初始化链表 */
    void InitSClist(List *list) {
        Node *s = (Node*)malloc(sizeof(Node));
        assert(s != NULL);
        list->first = list->last = s;
        list->last->next = list->first;//让链表最后一个结点的指针域指向头结点,从而时链表循环
        list->size = 0;
    }
     
    /* 尾部插入元素 */
    void push_back(List *list, ElemType x) {
        Node *s = _buynode(x);
        list->last->next = s; //尾插
        list->last = s; //赋地址
        list->last->next = list->first;
        list->size++;
    }
     
    /* 头部插入元素 */
    void push_front(List *list, ElemType x) {
        Node *s = _buynode(x);
        s->next = list->first->next; //头插
        list->first->next = s;
        if (list->last == list->first)
            list->last = s;
        list->size++;
    }
     
    /* 打印链表 */
    void show_list(List *list) {
        Node *p = list->first->next;
        while (p != list->first) {
            printf("%d->", p->data);
            p = p->next;
        }
        printf("Nul. ");
    }
     
    /* 尾部释放一个元素 */
    void pop_back(List *list) {
        if (list->size == 0)
    return;
        Node *p = list->first;
        while (p->next != list->last)
            p = p->next; //找到尾部节点的上一个节点
        free(list->last); //释放尾部元素
        list->last = p; //p节点赋给尾部节点
        list->last->next = list->first; //再使链表指向头节点
        list->size--;
    }
     
    /* 从头释放一个元素 */
    void pop_front(List *list) {
        if (list->size == 0)
    return;
        Node *p = list->first->next;
        list->first->next = p->next;
        if (list->size == 1) //判断表中是否只有一个元素
            list->last = list->first;
        free(p);
        list->size--;
    }
     
    /* 由小到大插入元素 */
    void insert_val(List *list, ElemType x) {
        Node *p = list->first;
        while (p->next != list->last && p->next->data < x) //轮询找出大于X的元素并在前面插入
            p = p->next;
        if (p->next == list->last && p->next->data < x) //只有一个元素
            push_back(list, x);
        else { //没有元素
            Node *s = _buynode(x);
            s->next = p->next;
            p->next = s;
            list->size++;
        }
    }
     
    /* 查找链表元素 */
    Node* find(List *list, ElemType key) {
        if (list->size == 0) //链表不存在
    return NULL;
        if (p == list->first) //链表为空
            return NULL;
     
        Node *p = list->first->next;
        while(p != list->first && p->data != key)
            p = p->next;
     
        return p;
    }
     
    /* 链表长度 */
    int length(List *list) {
        return list->size;
    }
     
    /* 删除链表元素 */
    void delete_val(List *list, ElemType x) {
        if (p == NULL) {
            return;
        }
        if (list->size == 0)
    return;
        Node *p = find(list, x); //找出元素
        if (p == list->last) //p为尾节点
            pop_back(list);
        else { //p不为尾节点,删除p
            Node *q = p->next;
            p->next = q->next;
            free(q);
            list->size--;
        }
    }
     
    /* 对循环单链表进行排序 */--------------?
    void sort(List *list) {
        if (list->size == 0 || list->size == 1) //链表长度为0或1不排序
    return;
        Node *s = list->first->next; //第一个元素节点
        Node *q = s->next; //第二个元素节点
        list->last->next = NULL; //断开链表连接
        list->last = s;
        list->last->next = list->first;
        while (q != NULL) {
            s = q;
            q = q->next;
            Node *p = list->first;
            while (p->next != list->last && p->next->data < s->data)
                p = p->next;
            if (p->next == list->last &&p->next->data < s->data) {
                list->last->next = s;
                list->last = s;
                list->last->next = list->first;
            }
            else {
                s->next = p->next;
                p->next = s;
            }
        }
    }
     
    /* 链表逆序 */ ---------------->
    void reverse(List *list) {
        if (list->size == 0 || list->size == 1) //没有元素或单个元素则忽略
    return;
        Node *p = list->first->next;
        Node *q = p->next;
        list->last->next = NULL;
        list->last = p;
        list->last->next = list->first;
        while (q != NULL) {
            p = q;
            q = q->next;
            p->next = list->first->next;
            list->first->next = p;
        }
    }
     
    /* 释放链表所有元素 */
    void clear(List *list) {
        Node *p = list->first->next;
        while (p != list->first) {
            list->first->next = p->next;
            free(p);
            p = list->first->next;
        }
        list->last = list->first;
        list->last->next = list->first;
        list->size = 0;
    }
     
    /* 摧毁链表 */
    void destroy(List *list) {
        clear(list);
        free(list->first);
        list->first = list->last = NULL;
    }
     
    /********************************************************
    * main函数
    /********************************************************/
    #include"SClist.h"
     
    void main() {
        List mylist;
        InitSClist(&mylist);
     
        ElemType item;
        Node *p = NULL;
        int select = 1;
        while (select) {
            printf("******************************************* ");
            printf("*[1]  push_back        [2]  push_front    * ");
            printf("*[3]  show_list           [4]  pop_back      * ");
            printf("*[5]  pop_front          [6]  insert_val    * ");
            printf("*[7]  find                    [8]  length        * ");
            printf("*[9]  delete_val         [10] sort          * ");
            printf("*[11] reverse             [12] clear         * ");
            printf("*[13*] destroy             [0]  quit_system   * ");
            printf("******************************************* ");
            printf("请选择:>>");
            scanf("%d", &select);
            if (select == 0) break;
            switch (select) {
            case 1:
                printf("请输入要插入的数据(-1结束):>");
                while ( scanf("%d", &item) && ( item != -1) ){
                    push_back(&mylist, item);
                }
                break;
            case 2:
                printf("请输入要插入的数据(-1结束):>");
                while ( scanf("%d", &item) && ( item != -1) ){
                    push_front(&mylist, item);
                }
                break;
            case 3:
                show_list(&mylist);
                break;
            case 4:
                pop_back(&mylist);
                break;
            case 5:
                pop_front(&mylist);
                break;
            case 6:
                printf("请输入要插入的数据:>");
                scanf("%d", &item);
                insert_val(&mylist, item);
                break;
            case 7:
                printf("请输入要查找的数据:>");
                scanf("%d", &item);
                p = find(&mylist, item);
                if (p == NULL)
                    printf("要查找的数据在单链表中不存在! ");
                break;
            case 8:
                printf("单链表的长度为%d ", length(&mylist));
                break;
            case 9:
                printf("请输入要删除的值:>");
                scanf("%d", &item);
                delete_val(&mylist, item);
                break;
            case 10:
                sort(&mylist);
                break;
            case 11:
                reverse(&mylist);
                break;
            case 12:
                clear(&mylist);
                break;
                //case 13: //推出再释放
                //destroy(&mylist);
                //break;
            default:
                printf("选择错误,请重新选择! ");
                break;
            }
        }
        destroy(&mylist);
    }
     
     

  • 相关阅读:
    LeetCode-top100-3. 无重复字符的最长子串
    最长单调递增子序列 POJ 3903 Stock Exchange .
    并查集 POJ 1988 Cube Stacking
    贪心初步 hdu1789 Doing Homework again
    并查集初步题目(2)
    并查集初步题目(1)
    【python】引用模块,以及初探__init__.py
    Python 模块里函数的调用方法和import语句的作用(初学者版)
    二分查找算法
    python之内置函数,匿名函数
  • 原文地址:https://www.cnblogs.com/ownDefine/p/10802087.html
Copyright © 2011-2022 走看看