链表实现直接选择排序

本文介绍了一种使用链表来实现直接选择排序的方法,并提供了完整的C语言代码示例。通过定义链表节点结构体,实现了寻找最小节点、节点交换及排序等功能。
#include"stdio.h"
#include"stdlib.h"
/****************************************************
copyright: self_chou
Filename:  directsort.c
AUthour : self_chou   Version: 1.0     Date: 2012.07
Description: 用链表实现直接选择排序
Function List:
              find(); 寻找链表中最小的结点并返回
              change();交换链表中指定结点的位置
              sort(); 调用前两个函数实现功能
*******************************************************/

typedef struct node
{
    int num;
    struct node *next;
}node;

node *head = NULL;
node *last = NULL;
node *flag = NULL;      //用来记录结点交换的位置,从链表头开始
print()
{
    node *p = head;
    while(p != NULL)
    {
        printf("%d ",p->num);
	p = p->next;
    }
    printf("\n");
}

node * find(node *head)
{
    node *min = head;
    while(head != NULL)
    {
        if(head->num < min->num)         //找指定头结点链表中最小的结点
	{
	    min = head;
	}
	head = head->next;
    }
    return min;
}

void change(node *q,node *p)
{
    node *pfront = NULL;
    node *qfront = NULL;
    node *find = head;
    node *temp = NULL;
    if( p == q)                      //交换分,是不是头结点,和结点相不相邻,四种情况
    {
        flag = p;
        return;
    }
    while( find != q)
    {
        qfront = find;
	find = find->next;
    }
    find = head;
    while( find != p)
    {
        pfront = find;
	find = find->next;
    }
    if( pfront == NULL)
    {
        if( qfront == head)
	{
	    p->next = q->next;
	    q->next = p;
	    head = q;
	    flag = q;
	}
	else
	{
            temp = p->next;           //注意temp指向next,这儿犯错了。。。
	    qfront->next = p;
	    p->next = q->next;
	    q->next = temp;
	    head = q;
	    flag = q;
	}
    }
    else
    {
        if( qfront == p)
	{
	    pfront->next = q;
	    p->next = q->next;
	    q->next = p;
	    flag = q;
	}
	else
	{
	    temp = q->next;
	    pfront->next = q;
	    q->next =p->next;
	    qfront->next = p;
	    p->next = temp;
	    flag = q;
	}
    }

}

void sort()
{
    node *p = head;
    node *min = NULL;                //实现程序的主要功能
    int n = 4;
    while(p != NULL)
    {
        min = find(p);
	change(min,p);
	p = flag;
	p = p->next;
    }
}

int main()
{
    int i ;
    int get;
    printf("please input the six num:\n");
    for(i = 1;i <= 6;i++)
    {
        scanf("%d",&get);
        node *p = (node *)malloc(sizeof(node));
	p->num = get;
	if(head == NULL)
	{
	    head = p;
	    last = p;
	}
	else
	{
	    last->next =p;
	    last = p;
	}
	last->next = NULL;
    }
    printf("排序前\n");
    print();
    flag = head;
    sort();
    printf("排序后\n");
    print();
    return 0;
}


  




                
### 链表实现简单选择排序算法的方法 简单选择排序是一种基础的排序算法,其核心思想是:**每一轮从未排序的元素中选择最小(或最大)的元素,将其放到已排序序列的末尾**。对于链表结构来说,选择排序需要通过遍历链表来找到最小(或最大)的节点,并进行相应的指针调整操作,以确保链表的连续性和正确性。 #### 算法思想 - **初始化**:检查链表是否为空或仅包含一个节点,如果是则直接返回。 - **外层循环**:从链表的第一个节点开始,逐步遍历到链表的最后一个节点。 - **内层循环**:在当前节点之后的链表中寻找最小值的节点。 - **交换操作**:将找到的最小值节点与当前节点交换数据。 - **结束条件**:当链表完全遍历完成时,排序结束。 #### 数据结构定义 链表的节点结构定义如下: ```c typedef struct LNode { int data; struct LNode *next; } LNode, *LinkList; ``` #### 算法实现 以下是链表实现简单选择排序的具体代码: ```c void SimpleSelectSortList(LinkList head) { LinkList p, q, s; int min, t; // 如果链表为空或仅包含一个节点,则直接返回 if (head == NULL || head->next == NULL) { return; } // 外层循环:从链表的第一个节点开始 for (q = head; q != NULL; q = q->next) { // 初始化最小值为当前节点的值,并记录最小值节点 min = q->data; s = q; // 内层循环:从当前节点的下一个节点开始遍历 for (p = q->next; p != NULL; p = p->next) { // 如果找到更小的值,更新最小值和对应的节点 if (min > p->data) { min = p->data; s = p; } } // 如果找到的最小值节点不是当前节点,则交换数据 if (s != NULL && s != q) { t = s->data; s->data = q->data; q->data = t; } } } ``` #### 算法分析 - **时间复杂度**:由于每一轮遍历需要比较 $O(n)$ 次,且总共有 $O(n)$ 轮,因此总的时间复杂度为 $O(n^2)$。 - **空间复杂度**:该算法仅使用常数级别的额外空间,因此空间复杂度为 $O(1)$。 - **稳定性**:简单选择排序是不稳定的排序算法,因为交换数据时可能会改变相同值节点的相对顺序。 #### 注意事项 - **空指针处理**:在操作链表时,必须确保指针不为空,否则会导致空指针异常。 - **指针操作**:在交换节点数据时,需要确保指针的正确性,避免链表断裂。 - **性能优化**:如果链表较长,可以通过添加尾部指针或优化遍历方式来减少不必要的遍历操作。 #### 示例输入输出 假设输入的链表为 `3 -> 1 -> 4 -> 2`,经过简单选择排序后,输出结果为 `1 -> 2 -> 3 -> 4`。 --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值