单向链表的相关操作总结:创建、删除、查找、排序、统计链表大小、链表的反转和遍历等

对单向链表的各种操作做了总结,并且考虑到了每个操作的特殊情况,对特殊情况也要求能够正确处理。

typedef struct link
{
    struct link *next;
    int date;
}Link,*List;

//链表的创建
List init()
{
    Link *st = malloc(sizeof(*st));
    if(st == NULL )
        {
            printf("Memory Erroy!\n");
            return NULL;
        }
    else
        st->next = NULL;
    return st;
}

List creat()
{
    Link *st = init(),*p;
    p = st;
    int k;
    while(p != NULL && scanf("%d",&k) != EOF) //默认EOF=-1,当scanf中输入ctrl+z时,返回值为-1
    {
        Link *temp = malloc(sizeof(*temp)); //头节点为空,
        temp->date = k;
        temp->next = NULL;
        p->next = temp;
        p = p->next;
    }
    return st->next;  //返回头结点的下一节点
}
//判断链表是否为空
int linkempty(List st)
{
    if(st == NULL)
            {
                printf("The one-way link is empty!\n");
                return 0;
            }
    else
        return 1;
}
//统计链表元素个数
int linksize(List st)
{
    int sum = 0;
    while(st != NULL)
        {
            sum++;
            st = st->next;
        }
    return sum;
}
//在顺序链表中插入元素,保持元素仍然有序
List orderinsert(List st,int k)
{
    Link *head = malloc(sizeof(*head));
    Link *pre,*p = head;
    pre = head;
    head->next = st;
    for(p = p->next;p != NULL;)
    {
        if(p->date > k)
            break;
        pre = p;
        p = p->next;
    }
    if(p == NULL)             //链表中元素都不大于k
    {
        Link *tmp = malloc(sizeof(*tmp));
        tmp->date = k;
        tmp->next = NULL;
        pre->next = tmp;
    }
    else
    {
        Link *tmp = malloc(sizeof(*tmp));
        tmp->date = k;
        tmp->next = p;
        pre->next = tmp;
    }
    return head->next;
}
//在无序链表中的第i个位置后插入元素k
List disorderinsert(List st,int i,int k)
{
    int t = 0;
    Link *p = st,*pre;
    if(i == 0)                   //在头节点处插入
    {
        printf("Insert to the head!\n");
        Link *tmp = malloc(sizeof(*tmp));
        tmp->date = k;
        tmp->next = p;
        st = tmp;
    }
    else
    {
        while(p != NULL && t < i)
      {
          t++;
          pre = p;
          p = p->next;
      }
      if(t <= i)
     {
        printf("Insert the new node to the tail!\n");
        Link *tmp = malloc(sizeof(*tmp));
        pre->next = tmp;
        tmp->date = k;
        tmp->next = NULL;
     }
     else
     {
        Link *tmp = malloc(sizeof(*tmp));
        pre = p->next;
        p->next = tmp;
        tmp->date = k;
        tmp->next = pre;
     }
    }
    return st;
}
//删除元素k
List datedelete(List st,int k) 
{
    Link *p, *pre = malloc(sizeof(*pre));
    int t = 0;
    p = st;
    if(p->next == NULL)  //链表为单节点链表
    {
        if(p->date == k)
            printf("Signle node link and %d is root.\n",k);
        else
            printf("Signle node link and NO %d !\n",k);
        return NULL;
    }
    else
    {
        pre->next = st;
        st = pre;
        while(pre->next != NULL)
        {
           p = pre->next;
        if(p->date == k)
          {
              pre->next = p->next;
              free(p);
              t++;
          }
        else
             pre = p;
        }
        if(!t)
        printf(" NO %d!\n",k);
    return st->next;
    }
}
//在顺序链表中删除第i个最小元素
List locatedelete(List st,int i)
{
    Link *p = st,*pre;
    int k,t = 1;
    k = p->date;
    pre = p->next;
    if(i == 1)  //删除最小元素(从头节点开始删除)
    {
        free(p);
        p = pre;
        while(p != NULL && p->date == k) //考虑有多个相同元素(算一个等级,如:第一个最小)的情况
        {
            pre = p->next;
            free(p);
            p = pre;
        }
        if(p == NULL)
            {
                printf("NULL!\n");
                return NULL;
            }
        else
            return p;
    }
    else     //删除第i个最小元素(i!=1,且第i个最小元素可能有多个)
    {
        p = p->next;
        while(p != NULL)
        {
            if(p->date != k)
            {
                t++;
                k = p->date;
            }
            if(t == i)
                break;
            else
            {
                pre = p;
                p = p->next;
            }
        }
        if(t < i)
            printf("The %dth min-date is NOT exist!\n",i);
        else
        {
            if(t == i)
            {
                pre->next = p->next;
                p = p->next;
                while(p != NULL && k == p->date)
                    {
                        pre->next = p->next;
                        p = p->next;
                    }
            }
        }
        return st;
    }
}
//查询元素k是否在链表中(0:链表中无此元素;否则元素存在)
int datesearch(List st,int k)
{
     Link *p = st;
     int i = 0;
     while(p != NULL)
     {
         if(p->date == k)
             i++;
          p = p->next;
     }
     return i;
}
//已知链表大小时寻找链表的中间元素
int middledateN(List st,int N)
{
      int i = 1;
      if(N%2 == 0)
      {
          while(i != N/2)
            {
                i++;
                st = st->next;
            }
          return st->date;
      }
      else
      {
          while(i != N/2)
            {
                i++;
                st = st->next;
            }
          return st->next->date;
      }
}
//链表大小未知时,寻找中间元素
int middledate(List st)
{
     Link *p,*mid;
     p = st;  
     mid = st;   //设置两个指针,mid为中间指针
     while(p->next != NULL)
     {
         p = p->next;
         if(p->next != NULL)
         {
             p = p->next;
             mid = mid->next;
         }
     }
     return (mid->date);
}
//链表的反转
List linkreverse(List st)
{
       if(st->next == NULL)
       {
           printf("Signle node link!\n");
           return st;
       }
       else if(st->next->next == NULL)
       {
           printf("Only two nodes!\n");
           Link *tmp = st->next;
           st->next->next = st;
           st->next = NULL;
           return tmp;

       }
       else
       {
           Link *pre, *p,*tmp;
           pre = NULL;
           p = st;
           while(p->next != NULL)
           {
               tmp = p->next;
               p->next = pre;
               pre = p;
               p = tmp;
           }
           p->next = pre;
           return p;
       }
}
//链表的遍历
void traverse(List st)
{

    while(st != NULL)
    {
         printf("%3d",st->date);
         st = st->next;
    }
    printf("\n");
    return;
}
//插入排序
List linkinsertsort(List st)
{
   Link *p,*head = malloc(sizeof(*head));
   Link *q;
   head->next = st;
   p = head;
   q = NULL;
   for(p = p->next;p != NULL;p = p->next)
       q = orderinsert(q,p->date);
    return q;
}
//将两个有序链表进行归并
List combine(List st1,List st2)
{
     Link *st = malloc(sizeof(*st));
     Link *p,*q,*head = st;
     p = st1;
     q = st2;
     while(p != NULL && p != NULL)
     {
         if(p->date < q->date)
         {
             st->next = p;
             st = p;
             p = p->next;
         }
         else
         {
             st->next = q;
             st = q;
             q = q->next;
         }
     }
     st->next = (p == NULL) ? q : p;
     return head->next;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值