c语言里单链表的创建与增减

单链表的创建与元素的增减等操作
/**
 * Single Way List
 * print all list after do a operator.
 * task1: 
 *  create: create a List which data is: 1, 4, 6, 2, 10, 11, 2
 *  add: add 3, 4, 1 to head of list (-> 3, 4, 1, 1, 4, 6, 2, 10, 11, 2)
 *  delete: delete 3, 6, 11, 1 in list  (->  4, 4, 2, 10, 2)
 * insert: insert 16 in 4th position of list (->  4, 4, 2, 16, 10, 2)
 *  insert: insert 20 after 10 in list (-> 4, 4, 2, 16, 10, 20, 2)
 *  find: find max element in list (-> 20)
 *  sort: sort list in asce order  (-> 2, 2, 4, 4, 10, 16, 20)
 *
 * task2:
 *  create: create list2 which data is 2, 3, 5, 1, 7, 8
 *  sort: sort list2 (-> 1, 2, 3, 5, 7, 8)
 *  merge: merge list2 to list keep asce order (-> 1, 2, 2, 2,  3, 4, 4, 5, 7, 8, 10, 16, 20) 
 *  set: remove repeat element (-> 1, 2, 3, 4, 5, 7, 8, 10, 16, 20)
*/

首先理解指针与二级指针,如果需要修改一个指针的指向,那么需要传二级指针,如果只修改指针指向地址的内容,则一级指针就可以。

  1. 首先定义单链表
typedef int T;

typedef struct ListNode
{
    T data;
    struct ListNode* next;
} List;
  1. 创建单链表
    如果分配一整块空间给单链表,释放的时候free一个指针就会把整个空间释放掉,不方便节点操作,因此一个一个节点创建:
    void create_list(List** list_p, T data[], int N){
    List* nex = malloc(sizeof(List));
    nex->data = data[N-1];
    nex->next = NULL;
    
    List* cur;
    for(int i = N-2; i >=0; i--){
        cur = malloc(sizeof(List));
        cur->data = data[i];
        cur->next = nex;
        nex = cur;
    }
    *list_p = cur;
    }
    
    
  2. 打印单链表
    void print_list(List* list){
    while(list != NULL){
        printf("%d, ", list->data);
        list = list->next;
    }
    printf("\n");
    }
    
  3. 在头部增加一个元素
    void add_element(List **list_p, T data){
    List* list = *list_p;
    List* new_node = malloc(sizeof(List));  // create a new node
    new_node->data = data;
    new_node->next = list;
    
    *list_p = new_node;
    }
    
  4. 删除一个元素
    void delete_element(List **list_p, T data){
    List* cur = *list_p;
    List* pre;
    
    //find a new head
    while(cur && cur->data == data){
        pre = cur;
        cur = cur->next;
        free(pre);
    }
    *list_p = cur;
    
    pre = cur;
    cur = cur->next;
    while(cur != NULL){
        // ->x->x-> ... ->null 
        if(cur->data == data){
            pre->next = cur->next;
            cur->next = NULL;
            free(cur);
            cur = pre->next;
        }
        else{
            pre = cur;
            cur = cur->next;
        }
    }
    }
    
    
  5. 测试
int main(){
  T data1[] = {1, 4, 6, 2, 10, 11, 2};
  List* list;
  T  n = 7;
  create_list(&list, data1, n);
  print_list(list);

  add_element(&list, 1);
  add_element(&list, 4);
  add_element(&list, 3);
  print_list(list);
  delete_element(&list, 3);
  print_list(list);
  delete_element(&list, 6);
  print_list(list);
  delete_element(&list, 11);
  print_list(list);
  delete_element(&list, 1);
  print_list(list);
  delete_element(&list, 0);
  print_list(list);
  return 0;
}

在这里插入图片描述
7. 在指定位置插入元素

int insert_position(List** list_p, T data, T position){
  List* list = *list_p;
  
  if(position == 1){  // insert in head
      add_element(list_p, data);
      return 1;
  }   

  for(int i=1; i<position-1; i++){
      if(!(list))
          return 0;
      list = list->next;
  }   
  // if list elements num < position-1
  if(!list)
      return 0;

  List* new_node = malloc(sizeof(List));
  new_node->data = data;
  new_node->next = list->next;
  list->next = new_node;
 
  return 1;
}

  1. 在某一个元素后面插入一个新元素
int insert_after_element(List* list_p, T data, T after_element){
  while(list_p){
      if(list_p->data != after_element)
          list_p = list_p->next;
      else break;
  }
  if(!list_p)
      return 0;

  List* new_node = malloc(sizeof(List));
  new_node->data = data;
/* in single way link list, insert to tail is the same as insert to middle    
   if(list_p->next){
      new_node->next = list_p->next;
      list_p->next = new_node;
  }else{  // insert in tail
      list_p->next = new_node;
      new_node->next = NULL;
  }
*/
  new_node->next = list_p->next;
  list_p->next = new_node;

  return 1;
}

  1. 找到某一个元素
List* find_max(List* list){
  List* max = list;

  while(list->next){
      list = list->next;
      if(list->data > max->data)
          max = list;
  }

  return max;
}

  1. 对单链表升序排序
void sort_in_asce(List** list_p){
  List* cur = *list_p;
  List  *min, *head, *head_pre, *min_pre;

  int len=0;
  while(cur){
      cur = cur->next;
      len++;
  }

  head_pre = NULL;
  min_pre = NULL;
  head = *list_p;
  for(int i=0;i<len-1; i++){
      // find min element
      min = head;
      cur = head;
      while(cur->next){
          if(min->data > cur->next->data){
              min_pre = cur;
              min = cur->next;
          }
          cur = cur->next;
      }
      // insert min between head_pre and head
      if(min != head){
          if(head == *list_p){ // insert in head
              min_pre->next = min->next;
              min->next = head;
              *list_p = min;
          }else{
              min_pre->next = min->next;
              head_pre->next = min;
              min->next = head;
          }
          head_pre = min;
      }else{
          head_pre = min;
          head = head->next;
      }
  }
}
  1. 合并两个链表并升序排序
void merge_2_list(List** list1_p, List** list2_p){
  sort_in_asce(list2_p);
  List* list1 = *list1_p;
  List* list2 = *list2_p;

  List *merge;
  List* merge_head = malloc(sizeof(List));
  merge_head->data = 0;
  merge_head->next = NULL;

  merge = merge_head;
  while(list1 && list2){
      if(list1->data < list2->data){
          merge->next = list1;            merge = merge->next;
          list1 = list1->next;
      }else{
          merge->next = list2;
          merge = merge->next;
          list2 = list2->next;
      }   
  }   
  if(list1)
      merge->next = list1;

  if(list2)
      merge->next = list2;
          
  *list1_p = merge_head->next;
  merge_head->next = NULL;
  free(merge_head);
}


  1. 删除重复元素
void remove_repeat_element(List* list){
  List *pre, *cur;
  List *tmp;
  
  pre = list;
  cur = list->next;
  while(cur){
      if(cur->data == pre->data){
          tmp = cur; 
          pre->next = cur->next;
          cur = cur->next;
          free(tmp);
      }else{
          pre = cur;
          cur = cur->next;
      }   
  }   
}

  1. 测试
int main(){
  T data1[] = {1, 4, 6, 2, 10, 11, 2};
  List* list;
  T  n = 7;
  create_list(&list, data1, n);
  print_list(list);

  //add by hng
  add_element(&list, 1);
  add_element(&list, 4);
  add_element(&list, 3);
  print_list(list);
  delete_element(&list, 3);
  print_list(list);
  delete_element(&list, 6);
  print_list(list);
  delete_element(&list, 11);
  print_list(list);
  delete_element(&list, 1);
  print_list(list);
  delete_element(&list, 0);
  print_list(list);

  printf("\n");
  if(insert_position(&list, 16, 4))
      print_list(list);
  else
      printf("insert position false\n");

  printf("\n");
  if(insert_after_element(list, 20, 10))
      print_list(list);
  else
      printf("insert atfer elemnt false\n");

  List* max = find_max(list);
  printf("max element in list is %d\n",max->data);

  sort_in_asce(&list);
  print_list(list);
   
  T data2[] = {2, 3, 5, 1, 7, 8};
  List* list2;
  n = 6;
  create_list(&list2, data2, n);
  printf("list2: \n");
  print_list(list2);

  sort_in_asce(&list2);
  print_list(list2);

  merge_2_list(&list, list2);
  print_list(list);

  remove_repeat_element(list);
  print_list(list);

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值