链表排序(先插入,后排序(排序是调换结点的位置,不是换结点内的值))

#include <stdio.h>
#include <stdlib.h>         //调用malloc函数,返回值为void
#include <time.h>
 
 
struct node                 // 创建链表节点
{                           
    int num;                //成员1为数据
    struct node * next;     //成员2为和自己同类型的指针
};
 
typedef struct node Node;   //将链表节点重命名为Node
typedef struct node * Link; //将链表节点指针重命名为Link
 
 //函数功能:创建链表
void Create_link(Link *head)
{
    *head = NULL;                   //将空链表指向NULL,防止野指针
}
 
 //函数功能:插入,插入方式:尾插
void Insert_node_tail(Link  * head,Link  new_node)
{
    Link p;                         //定义一个结构体指针,用来移动链表,保护头指针
 
    p = *head;
 
    if (p == NULL)                  //如果链表是空链表。则将新节点作为头节点
    {
        new_node->next = NULL;      //新节点的指针指向NULL
        *head = new_node;           //头指针指向新节点
    }
    else                            //否则找到链表的尾节点
    {
        while (p->next != NULL)     //判断是否到尾节点
        {
            p = p->next;            //节点向后移动
        }
 
        new_node->next = NULL;      //移动到尾节点之后,让新节点指向NULL
        p->next = new_node;         //原来的尾节点指向新节点
    }
 
}
 
 //函数功能:打印链表
void Display(Link head)
{
    Link p;
 
    p = head;                       //将头指针赋值给别人,保护头指针
    if (head == NULL)               //链表为空
    {
        printf("Link is empty!\n"); //输出链表为空
    }
 
    while (p != NULL)               //当p指针不指向空
    {
        printf("num = %d\n",p->num);//将p指向的数据输出
        p = p->next;                //p指向下一个节点
    }
}
 //函数功能:释放结点
void Release(Link * head)       
{
    Link p;                         //保护头节点
 
    while (*head != NULL)           //头节点不指向空
    {
        p = *head;                  //存一下头节点
        *head = (*head)->next;      //头节点后移
        free(p);                    //释放p指向的节点
    }
}
 
 //函数功能:求链表的长度并返回
int Link_len(Link head)
{
    int count = 0;
 
    while (head != NULL)
    {
        count++;
        head = head->next;
    }
 
    return count;
}
 
 //进行排序
void Sort(Link * head)
{
 
    int len;
 
    len = Link_len(*head);
 
    if (len <= 1)//只有1个结点
    {
        return;
    }
    else if (len == 2)//有2个结点
    {
        Link p,q;
 
        p = *head;
        q = (*head)->next;
 
        if (p->num > q->num)
        {
            *head = q;
            q->next = p;
            p->next = NULL;
        }
    }
    else//至少3个结点
    {
        Link p,q,x,y;
 
        q = (*head)->next;
        //开始比较大小,先跟头结点进行比较
        if ((*head)->num > q->num)
        {
            (*head)->next = q->next;
            q->next = *head;
            *head = q;
        }
 
        q = y = (*head)->next; 
        //比较完之后指针q向后移动
        while (q->next != NULL)
        {
            q = q->next;
 
            x = *head;
 
            p = x->next;
            //将q和x,p都进行比较
            while (p != q)
            {
                if (x == *head)
                {
                    if (x->num > q->num)
                    {
                        y->next = q->next;
                        q->next = x;
                        *head = q;
                        q = y;
                        break;
                    }
                }
                if (p->num > q->num)
                {
                    x->next = q;
                    y->next = q->next;
                    q->next = p;
                    q = y;
                    break;
                }
                x = p;
                p = p->next;
            }
 
            y = q;
 
        }
 
        return;
    }
}
 
int main()
{
    srand((unsigned)time(NULL));
 
    Link head;
    Link new_node;
 
    int i,n;
 
    Create_link(&head);     // 创建链表, 将地址传过去,带回地址
 
 
    for (i = 0;i < 10; i++)
    {
        n = rand()%100;
 
        new_node = (Link)malloc(sizeof(Node));
 
        new_node->num = n;
 
        Insert_node_tail(&head,new_node);
    }
 
    Display(head);
 
    Sort(&head);
 
    Display(head);
 
    Release(&head);
 
    Display(head);
 
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值