欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2023-10-15 09:46:54
c/c++ 线性表之单向循环链表 线性表之单向循环链表 不是存放在连续的内存空间,链表中的每个节点的next都指向下一个节点,最后一个节点的下一个节点不是NULL,而是头节点。因为头尾相连,所以叫单向循环链表。 真实的第一个节点是头节点,头节点不存放数据,单纯为了编写程序方便。但是下面注释里写的【第 ......

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\n");
}

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("*****************************************\n");
    printf("*** [1]   push_back   [2]  push_front ***\n");
    printf("*** [3]   show_list   [4]  pop_back   ***\n");
    printf("*** [5]   pop_front   [6]  insert_val ***\n");
    printf("*** [7]   find        [8]  length     ***\n");
    printf("*** [9]   delete_val  [10] sort       ***\n");
    printf("*** [11]  sort        [12] resver     ***\n");
    printf("*** [13]              [14] clear      ***\n");
    printf("*** [0]   quit        [15*]destroy    ***\n");
    printf("*****************************************\n");
    printf("请选择:>");
    scanf("%d", &select);
    if(0 == select)
      break;
    switch(select){
    case 1:
      printf("请输入要插入的数据,以-1结束>\n");
      while(scanf("%d",&item) && item != -1){
    push_back(&list, item);
      }
      show_list(&list);
      break;
    case 2:
      printf("请输入要插入的数据,以-1结束>\n");
      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("请输入要插入的数据>\n");
      scanf("%d",&item);
      insert_val(&list, item);
      show_list(&list);
      break;
    case 7:
      printf("please enter what you shoule find out>\n");
      scanf("%d",&item);
      node = find(&list, item);
      if(node == NULL){
    printf("can not find %d\n", item);
      }
      break;
    case 8:
      printf("length is %ld\n", list.size);
      break;
    case 9:
      printf("please enter what you want to delete>\n");
      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);
}