单链表的操作实现

#include <stdlib.h>  /* malloc */
#include <stdio.h>
typedef struct _node {
 int data;
 struct _node *next;
} node;
/* 此程序中的单链表带头结点.
 * 基本操作:
 * 创建
 * 插入
 * 删除
 * 长度
 * 打印
 * 排序
 * 逆置
 * 求中
 * 合并
 * 去重
 */
node *create(int num);
void print(node *L);
int getlength(node *L);
node *delete(node *L, int val);
node *insert(node *L, int val);
node *sort(node *L);
node *reverse(node *L);
int getmid(node *L);
node *merge(node *L1, node *L2);
node *delrepeat(node *L);
int main()
{
  int count, val;
  node *list_a, *list_b, *list_c;
  printf("Input node number: ");
  scanf("%d", &count);
  list_a = create(count);
  printf("Original list: ");
  print(list_a);
  
  val = getmid(list_a);
  printf("Middle value = %d/n", val);
  int len;
  len = getlength(list_a);
  printf("Len = %d/n", len);
  printf("Reversing result: ");
  reverse(list_a);
  print(list_a);


  printf("Sorting result: ");
  sort(list_a);
  print(list_a);
  printf("Input value to delete: ");
  scanf("%d", &val);
  delete(list_a, val);
  print(list_a);
  printf("Input value to insert: ");
  scanf("%d", &val);
  insert(list_a, val);
  print(list_a);
  printf("Input node number(list_b): ");
  scanf("%d", &count);
  list_b = create(count);
  sort(list_b);
  
  printf("Original list(list_a and list_b): /n");
  print(list_a);
  print(list_b);
  list_c = merge(list_a, list_b);
  printf("Merge result: ");
  print(list_c);
  printf("Delete repeat result: ");
  delrepeat(list_c);
  print(list_c); 
  return 0;
}
/* Create */
node *create(int num)
{
 node *head, *p, *n;
 head = (node *)malloc(sizeof(node)); // remember head node has no data.
 p = head;
 while (num > 0)
 {
  n = (node *)malloc(sizeof(node));
  printf("Input: ");
  scanf("%d", &(n->data));
  p->next = n; // 连接到尾部
  p = n;
  num--;
 }
 p->next = NULL;
 return head;
}
/* Print */
void print(node *L)
{
 node *it;
 if (L->next != NULL)
 {
   it = L->next;
   while (it != NULL)
   {
     printf("%d ", it->data);
     it = it->next;
   }
   printf("/n"); 
 }
 else 
   printf("This is a empty List./n");
 return;
}
int getlength(node *L)   // not include head node.
{
 node *it = L->next;
 int  len = 0;
 while (it != NULL)
 {
     len++;     
     it = it->next;
 }
 return len;
}
 
node *sort(node *L)
{
 int t, i, j, flag, len = 0;
 
 node *head, *p;
 head = L;
 p = L->next;
 while (p != NULL)
 {
  len++;
  p = p->next;
 }
 if (len<2)  // 少于2个节点直接不处理.
  return (head);
 p = L->next;
 for (i=1; i<len; i++) // 使用冒泡排序.
 {
  flag = 0;
  p = L->next;  // 归位, 非常重要!!!
  for (j=1; j<len-i+1; j++)
  {
    if (p->data > p->next->data)
    {
       flag = 1;
       t = p->data;
       p->data = p->next->data;
       p->next->data = t;
    }
   p = p->next;
  }
  if (flag == 0)
   break;
 }
 return (head); 
}
/* 前提是单链表是有序的, 单调不减. 使用sort() */
node *delete(node *L, int val)
{
 node *head, *p, *b;
 head = L;
 b = L;
 p = b->next;
 while (p != NULL && p->data != val)
 { 
   b = p; 
   p = p->next; 
 }
 if (p != NULL)
 {
  b->next = p->next;
  free(p);
  p = NULL;
 }
 else
  printf("Not find node of value: %d/n", val);
 return (head);
}
/* 前提是单链表是有序的, 单调不减. 使用sort() */
node *insert(node *L, int val)
{
 node *head, *p, *b;
 head = L;
 b = L;
 p = b->next;
 node *n = (node*)malloc(sizeof(node));
 n->data = val;
 n->next = NULL;
 while(p != NULL && p->data < val)
 {
  b = p;
  p = p->next;
 }
 if (p != NULL)
 {
  b->next = n;
  n->next = p;
 }
 else
 {
  b->next = n;
 }
 return (head);
}


node *reverse(node *L)
{
 node *head, *b, *p, *n;
 head = L;
 b = NULL; // important.尾指针
 p = head->next;
 if (p == NULL || p->next == NULL)  // node number<2
  return (head);
 n = p->next;
 while (p->next != NULL)
 {
  p->next = b;
  b = p;
  p = n;
  n = p->next;
 }
 p->next = b; // important, 否则只得到一个节点,其他的都会丢掉.
 head->next = p;
 return (head);
}
int getmid(node *L) // 按照中间点 = n/2原则
{
 node *mid, *p;
 mid = p = L->next;
 while (p != NULL && p->next != NULL && p->next->next != NULL)
 {
  p = p->next->next;
  mid = mid->next;
 }
 return (mid->data);
}
node *merge(node *L1, node *L2) // 如果允许重复, 不需要free任何节点.
{
 node *head, *p, *p1, *p2, *d;
 head = p = L1;
 p1 = L1->next;
 p2 = L2->next;
 while (p1 != NULL && p2 != NULL)
 {
  if (p1->data < p2->data)
  {
   p->next = p1; 
   p = p1;
   p1 = p1->next;
  }
  else if (p1->data > p2->data)
  {
   p->next = p2;
   p = p2;
   p2 = p2->next;
  }
  else
  {
   p->next = p1;
   p = p1;
   p1 = p1->next;
   p->next = p2;
   p = p2;
   p2 = p2->next;
  }
 } // end of while.
 if (p1 != NULL)
  p->next = p1;
 if (p2 != NULL)
  p->next = p2;
 free(L2); // 将L2头节点释放!
 L2 = NULL;
 return (head); 
}
node *delrepeat(node *L)  // 在有序的基础之上进行.
{
 node *head, *p, *n, *t;
 head = L;
 p = head->next;
 while (p != NULL && p->next != NULL)
 {
  n = p->next;
  while (n != NULL && p->data == n->data)
  {
   t = n;
   n = n->next;
   free(t);
   t = NULL;
   p->next = n;
  }
  p = p->next;
 }
 // p->next = NULL;  // 情形: 1. 最后结点保留; 2. 最后结点删除, 则此时已有p=NULL.
 return (head);
}



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值