算法总结之 单链表的选择排序

给定一个无序单链表的头节点head,实现单链表的选择排序

要求额外空间复杂度O(1)

思路:

既然额外空间复杂度O(1),就不能把链表装进容器,排好序后再从新链接,而是要求面试者在原链表上利用有限几个变量完成选择排序的过程。

选择排序是从未排序的部分找到最小值,然后放到排好序部分的尾部。

1 开始时默认真个链表都是未排序的部分,对于找到的最小值节点肯定是整个链表的最小值节点,将其设置为新的头节点记:newHead

2 每次在排序的部分中找到最小值的节点,然后哦把这个节点从未排序的链表删除,删除的过程保证未排序的不能断开

3 把删除的节点链接到排好序的后面

4 全部过程处理完后,整个链表已经有序,返回newHead

package TT;

public class Test111 {

    public static class Node{
         public int value;
         public Node next;

         public Node(int data){
             this.value=data;
         }
    }

    public static Node selectionSort(Node head){

        Node tail=null;
        Node cur = head;

        Node smallPre = null;
        Node small=null;

        while(cur !=null){
            small=cur;
            smallPre=getSmallestPreNode(cur);
            if(smallPre !=null){
                small = smallPre.next;
                smallPre.next=small.next;  //删除掉
            }
            cur=cur==small ? cur.next :cur;   //看看当前的值是不是最小的那个
            if(tail==null){
                head=small;  //第一个
            }else {
                tail.next=small;
            }
            tail=small;  //更新下尾部
        }
          return head;
    }

    public static Node getSmallestPreNode(Node head){

          Node smallPre=null;
          Node small=head;
          Node pre = head;
          Node cur=head.next;

        while(cur!=null){
            if(cur.value <small.value){
                smallPre=pre;
                small=cur;
            }
            pre=cur;
            cur=cur.next;
        }
        return smallPre;
    }

}
时间: 2024-07-29 01:22:21

算法总结之 单链表的选择排序的相关文章

[程序员代码面试指南]链表问题-单链表的选择排序(选择排序)

题意 给定一个无序单链表的头节点head,实现单链表的选择排序. 题解 按选择排序方法:每次从原链表找出最小值,从原链表删除,插入新的有序链表. 时间复杂度O(n^2) 额外空间复杂度O(1) 代码 public class Main { public static void main(String args[]) { Node n1=new Node(2); Node n2=new Node(1); Node n3=new Node(3); n1.next=n2; n2.next=n3; No

009实现一个算法来删除单链表中的一个结点,只给出指向那个结点的指针(keep it up)

呵呵,这个题不能直接删除已知的结点,因为是单链表,不知道前驱,只知道 后继结点,直接删除会使链表断开.不过我们可以删除已知结点的后继结点, 把后继结点的值赋值给已知结点. #include <iostream> struct Node { int data; Node* next; }; bool removeNode(Node* vNode) { if (vNode == NULL || vNode->next == NULL) return false; Node* pNext =

实现一个算法从一个单链表中返回倒数第n个元素(keep it up)

我们维护两个指针, 它们之间的距离为n.然后,我将这两个指针同步地在这个单链表上移动,保持它们的距离 为n不变.那么, 当第二个指针指到空时,第一个指针即为所求. #include <iostream> struct Node { int data; Node* next; }; void initList(Node* vNode) { for (int i=0; i < 20; ++i) { Node* TempNode = new Node; TempNode->data =

cc150:实现一个算法来删除单链表中间的一个结点,只给出指向那个结点的指针

实现一个算法来删除单链表中间的一个结点,只给出指向那个结点的指针. 例子: 输入:指向链表a->b->c->d->e中结点c的指针 结果:不需要返回什么,得到一个新链表:a->b->d->e 解答 这个问题的关键是你只有一个指向要删除结点的指针,如果直接删除它,这条链表就断了. 但你又没办法得到该结点之前结点的指针,是的,它连头结点也不提供.在这种情况下, 你只能另觅他径.重新审视一下这个问题,我们只能获得从c结点开始后的指针, 如果让你删除c结点后的某个结点,那

算法效率的分析--【以选择排序与冒泡排序为基础】

在前面我们实现了选择排序与冒泡排序的具体实现,现在我们从数学的角度分析下算法的效率问题: 首先我们把两种排序算法的概念重温一遍: 选择排序:在每一轮中,找出最小的元素放在他最终的位置.挺起来有些别扭,我们举个实例: eg:        8, 5,1, 20, 6, 3 1ed······  1, 5,8, 20, 6, 3 2ed······  1, 3, 8,20, 6,5 3ed······  1, 3,5, 20, 6, 8 4ed······  1, 3,  5, 6,  20,8 5

cc150:实现一个算法来删除单链表中间的一个结点,仅仅给出指向那个结点的指针

实现一个算法来删除单链表中间的一个结点,仅仅给出指向那个结点的指针. 样例: 输入:指向链表a->b->c->d->e中结点c的指针 结果:不须要返回什么,得到一个新链表:a->b->d->e 解答 这个问题的关键是你仅仅有一个指向要删除结点的指针,假设直接删除它,这条链表就断了. 但你又没办法得到该结点之前结点的指针,是的,它连头结点也不提供.在这样的情况下, 你仅仅能另觅他径.又一次审视一下这个问题,我们仅仅能获得从c结点開始后的指针, 假设让你删除c结点后的

4.2.2 算法之美--单链表实现

按照书上的要求实现了一下单链表:单链表的实现可能以前看过几次了:现在想想最主要的几个操作算法应该能够写了吧:遇到的问题: 1. 链表节点写成private;所已给出了访问的接口: 2.模板类的.h和.cpp实现写在同一个文件: 3.感觉以后的数据结构实现还是用纯c的实现好一些:然后书主要是思路 节点类: #ifndef SINGLELIST_LISTNODE_H_ #define SINGLELIST_LISTNODE_H_ template <class T> class ListNode

数据结构之自建算法库——循环单链表

本文针对数据结构基础系列网络课程(2):线性表中第13课时双链表. 按照"0207将算法变程序"[视频]部分建议的方法,建设自己的专业基础设施算法库. 双链表算法库算法库采用程序的多文件组织形式,包括两个文件: 1.头文件:clinklist.h,包含定义双链表数据结构的代码.宏定义.要实现算法的函数的声明: #ifndef CLINKLIST_H_INCLUDED #define CLINKLIST_H_INCLUDED //循环单链表基本运算函数 typedef int ElemT

常见算法题:单链表二路归并

题目:现有两个递增的单链表L1和L2,设计一个算法将L1与L2的所有结点归并到递增的单链表L3中.要求:空间复杂度为O(1). 思路:本题可采用二路归并思路,但题目要求空间复杂度为O(1),因此不能复制结点,只能破坏L1和L2将结点插入到L3中. 代码: void Merge(LinkList &L1,LinkList &L2,LinkList &L3) { LinkList *p=L1.head->next, *q=L2.head->next; LinkList *p