zoukankan      html  css  js  c++  java
  • c/c++ 线性表之单向循环链表

    c/c++ 线性表之单向循环链表

    线性表之单向循环链表

    不是存放在连续的内存空间,链表中的每个节点的next都指向下一个节点,最后一个节点的下一个节点不是NULL,而是头节点。因为头尾相连,所以叫单向循环链表。

    真实的第一个节点是头节点,头节点不存放数据,单纯为了编写程序方便。但是下面注释里写的【第一个节点】的含义是头节点的下一节点,也就是真实存放数据的第一个节点。

    下面的代码实现了以下功能

    函数 功能描述
    push_back 从链表的最后插入节点
    push_front 从链表的起始插入节点
    show_list 打印出链表里每个节点的值
    pop_back 删除链表最后一个节点
    pop_front 删除链表起始节点
    insert_val 在合适的位置插入一个节点;
    比如原来的链表:1->3->NULL,当要插入的节点的值为2的时候,就会在1和3之间插入这个节点,插入后的链表:1->2->3->NULL
    find 查找指定的节点
    length 返回链表中节点的个数
    delete_val 删除指定的节点
    sort 排序,重新排列节点
    resver 按倒序,重新排列节点
    clear 释放除了头节点之外的所有节点所占用的内存空间
    destroy 释放所有节点的所占用的内存空间,包括头节点

    whilenode.h

    #ifndef __SEQNODE__
    #define __SEQNODE__
    
    #include <stdio.h>
    #include <malloc.h>
    #include <assert.h>
    #include <memory.h>
    #include <stdbool.h>
    
    #define ElemType int
    
    typedef struct Node{
      ElemType data;
      struct Node* next;
    }Node;
    
    typedef struct NodeList{
      Node*  first;
      Node*  last;
      size_t size;
    }NodeList;
    
    void init(NodeList*);
    void push_back(NodeList*, ElemType);
    void push_front(NodeList*, ElemType);
    void pop_back(NodeList*);
    void pop_front(NodeList*);
    void show_list(NodeList*);
    void insert_val(NodeList*, ElemType);
    Node* find(NodeList*, ElemType);
    void delete_val(NodeList*, ElemType);
    void sort(NodeList*);
    void sort1(NodeList*);
    void resver(NodeList*);
    void resver1(NodeList*);
    void resver2(NodeList*);
    void clear(NodeList*);
    void destroy(NodeList*);
    
    #endif
    

    whilenode.c

    #include "seqnode.h"
    
    void init(NodeList* list){
      list->first = (Node*)malloc(sizeof(Node));
      list->last = list->first;
      list->last->next = NULL;
      list->size = 0;
    }
    
    Node* create_node(ElemType val){
      Node* node = (Node*)malloc(sizeof(Node));
      assert(NULL != node);
      node->data = val;
      node->next = NULL;
      return node;
    }
    void push_back(NodeList* list, ElemType val){
      Node* p = create_node(val);
    
      list->last->next = p;
      list->last = p;
      list->last->next = list->first;
      list->size++;
    }
    
    void push_front(NodeList* list, ElemType val){
      Node* p = create_node(val);
    
      p->next = list->first->next;
      list->first->next = p;
      if(list->size == 0){
        list->last = p;
        list->last->next = list->first;
      }
      list->size++;
    }
    
    void show_list(NodeList* list){
      Node* tmp = list->first->next;
      while(tmp != list->first){
        printf("%d->", tmp->data);
        tmp = tmp->next;
      }
      printf("NULL
    ");
    }
    
    void pop_back(NodeList* list){
      if(list->size == 0)return;
      Node* p = list->first;
      while(p->next != list->last){
        p = p->next;
      }
      p->next = list->first;
      free(list->last);
      list->last = p;
      list->size--;
    }
    void pop_front(NodeList* list){
      if(list->size == 0)return;
      Node* p = list->first->next;
      list->first->next = p->next;
      if(list->size == 1){
        list->last = list->first;
      }
      list->size--;
      free(p);
    }
    void insert_val(NodeList* list, ElemType val){
      if(list->size == 0){
        push_back(list, val);
        return;
      }
      Node* p = create_node(val);
    
      Node* t = list->first;
      while(t->next != list->first && val > t->next->data){
        t = t->next;
      }
      if(t->next == list->first){
        list->last = p;
      }
      p->next = t->next;
      t->next = p;
      
      list->size++;
    }
    //寻找目标节点
    Node* find(NodeList* list, ElemType val){
      if(0 == list->size){
        return NULL;
      }
      Node* p = list->first->next;
      do{
        if(val == p->data){
          return p;
        }
        p = p->next;
      }
      while(list->first != p);
      return NULL;
    }
    //寻找目标节点的前一个节点
    Node* find1(NodeList* list, ElemType val){
      if(0 == list->size){
        return NULL;
      }
      Node* p = list->first;
      do{
        if(p->next->data == val){
          return p;
        }
        p = p->next;
      }while(list->first != p);
      return NULL;
    }
    void delete_val(NodeList* list, ElemType val){
      if(0 == list->size)return;
     
      Node* p = find1(list, val);
      if(NULL == p)return;
      if(p->next == list->last){
        list->last = p;
      }
      Node* tmp = p->next;
      p->next = p->next->next;
      free(tmp);
      list->size--;
    }
    
    void sort(NodeList* list){
      if(list->size == 0 || list->size == 1)return;
    
      Node* p = list->first->next;
    
      Node* t = list->last = list->first;
      list->last->next = list->first;
    
      size_t s = list->size;
    
      while(s-- > 0){
        while(p->data > t->next->data && t->next != list->first){
          t = t->next;
        }
        if(t->next == list->first){
          list->last = p;
        }
    
        Node* tmp = p->next;
        p->next = t->next;
        t->next = p;
    
        p = tmp;
        t = list->first;
      }
      list->last->next = list->first;
    }
    void resver(NodeList* list){
      if(list->size == 0 || list->size == 1)return;
    
      Node* head = list->first->next;
      Node* end = head;
    
      list->last = list->first;
      list->last->next = list->first;
      
      while(head != list->first){
        Node* tmp = head->next;
      
        head->next = list->first->next;
        list->first->next = head;
        
        head = tmp;
      }
      list->last = end;
    }
    
    void clear(NodeList* list){
      if(list->size == 0) return;
      Node* b = list->first->next;
      Node* q;
      while(b != list->first){
        q = b->next;
        free(b);
        b = q;
      }
      list->last = list->first;
      list->last->next = list->first;
      list->size = 0;
    }
    
    void destroy(NodeList* list){
      Node* b = list->first;
      Node* q;
      while(b != list->first){
        q = b->next;
        free(b);
        b = q;
      }
    }
    

    whilenodemain.c

    #include "seqnode.h"
    
    int main(){
      NodeList list;
      init(&list);
      int select = 1;
      ElemType item;
      Node* node = NULL;
      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]  sort        [12] resver     ***
    ");
        printf("*** [13]              [14] clear      ***
    ");
        printf("*** [0]   quit        [15*]destroy    ***
    ");
        printf("*****************************************
    ");
        printf("请选择:>");
        scanf("%d", &select);
        if(0 == select)
          break;
        switch(select){
        case 1:
          printf("请输入要插入的数据,以-1结束>
    ");
          while(scanf("%d",&item) && item != -1){
    	push_back(&list, item);
          }
          show_list(&list);
          break;
        case 2:
          printf("请输入要插入的数据,以-1结束>
    ");
          while(scanf("%d", &item) && item != -1){
    	push_front(&list, item);
          }
          show_list(&list);
          break;
        case 3:
          show_list(&list);
          break;
        case 4:
          pop_back(&list);
          show_list(&list);
          break;
        case 5:
          pop_front(&list);
          show_list(&list);
          break;
        case 6:
          printf("请输入要插入的数据>
    ");
          scanf("%d",&item);
          insert_val(&list, item);
          show_list(&list);
          break;
        case 7:
          printf("please enter what you shoule find out>
    ");
          scanf("%d",&item);
          node = find(&list, item);
          if(node == NULL){
    	printf("can not find %d
    ", item);
          }
          break;
        case 8:
          printf("length is %ld
    ", list.size);
          break;
        case 9:
          printf("please enter what you want to delete>
    ");
          scanf("%d",&item);      
          delete_val(&list, item);
          show_list(&list);
          break;
        case 10:
          // sort(&list);
          //show_list(&list);
          break;
        case 11:
          sort(&list);
          show_list(&list);
          break;
        case 12:
          resver(&list);
          show_list(&list);
          break;
        case 13:
          resver(&list);
          show_list(&list);
          break;
        case 14:
          clear(&list);
          show_list(&list);
          break;
        case 15:
          destroy(&list);
          break;
        default:
          break;
        }
      }
    
      destroy(&list);
    }
    
  • 相关阅读:
    Jzoj4822 完美标号
    Jzoj4822 完美标号
    Jzoj4792 整除
    Jzoj4792 整除
    Educational Codeforces Round 79 A. New Year Garland
    Good Bye 2019 C. Make Good
    ?Good Bye 2019 B. Interesting Subarray
    Good Bye 2019 A. Card Game
    力扣算法题—088扰乱字符串【二叉树】
    力扣算法题—086分隔链表
  • 原文地址:https://www.cnblogs.com/xiaoshiwang/p/9232056.html
Copyright © 2011-2022 走看看