1. 程式人生 > >單鏈表排序之選擇排序(贊)

單鏈表排序之選擇排序(贊)

單鏈表排序是單鏈表的常見程式設計任務之一,也是面試中經常出現的題目。單鏈表排序的關鍵是交換演算法,需要額外考慮。選擇排序是比較直觀的排序演算法之一,這裡就使用選擇排序實現單鏈表的排序。

LinkList SelectSort2(LinkList L)
{
    LinkList p,q,small;
    int temp;

    for(p = L->next; p->next != NULL; p = p->next)
    {
        small = p;
        for(q = p->next; q; q = q->next)
        {
            if(q->data < small->data)
            {
                small = q;
            }
        }
        printf("迴圈後,獲得最小值為:%d, 此時連結串列為:", small->data);
        if(small != p)
        {
            temp = p->data;
            p->data = small->data;
            small->data = temp;
        }
        ListTraverse(L);
    }
    printf("輸出排序後的數字:\n");
    return L;
}

或者

LinkList SelectSort(LinkList L)
{
    LinkList first;     /*排列後有序鏈的表頭指標*/
    LinkList tail;      /*排列後有序鏈的表尾指標*/
    LinkList p_min;     /*保留鍵值更小的節點的前驅節點的指標*/
    LinkList min;       /*儲存最小節點*/
    LinkList p;         /*當前比較的節點*/

    first = NULL;
    while (L != NULL) /*在連結串列中找鍵值最小的節點。*/
    {
        /*注意:這裡for語句就是體現選擇排序思想的地方*/
        for (p=L,min=L; p->next!=NULL; p=p->next) /*迴圈遍歷連結串列中的節點,找出此時最小的節點。*/
        {
            if (p->next->data < min->data) /*找到一個比當前min小的節點。*/
            {
                p_min = p; /*儲存找到節點的前驅節點:顯然p->next的前驅節點是p。*/
                min = p->next; /*儲存鍵值更小的節點。*/
            }
        }

        /*上面for語句結束後,就要做兩件事;
            一是把它放入有序連結串列中;
            二是根據相應的條件判斷,安排它離開原來的連結串列。*/

        /*第一件事*/
        if (first == NULL) /*如果有序連結串列目前還是一個空連結串列*/
        {
            first = min; /*第一次找到鍵值最小的節點。*/
            tail = min; /*注意:尾指標讓它指向最後的一個節點。*/
        }
        else /*有序連結串列中已經有節點*/
        {
            tail->next = min; /*把剛找到的最小節點放到最後,即讓尾指標的next指向它。*/
            tail = min; /*尾指標也要指向它。*/
        }
        /*第二件事*/
        if (min == L) /*如果找到的最小節點就是第一個節點*/
        {
            //printf("表頭%d已經是最小,當前結點後移。\n", min->data);
            L = L->next; /*顯然讓head指向原head->next,即第二個節點,就OK*/
        }
        else /*如果不是第一個節點*/
        {
            p_min->next = min->next; /*前次最小節點的next指向當前min的next,這樣就讓min離開了原連結串列。*/
        }
    }
    if (first != NULL) /*迴圈結束得到有序連結串列first*/
    {
        tail->next = NULL; /*單向連結串列的最後一個節點的next應該指向NULL*/
    }
    L = first;
    return L;
}

完整的可執行程式:
#include "stdio.h"

#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0

typedef int Status;/* Status是函式的型別,其值是函式結果狀態程式碼,如OK等 */
typedef int ElemType;/* ElemType型別根據實際情況而定,這裡假設為int */

typedef struct Node
{
    ElemType data;
    struct Node *next;
} Node;
typedef struct Node *LinkList; /* 定義LinkList */

Status visit(ElemType c)
{
    printf("->%d",c);
    return OK;
}

/* 初始化順序線性表 */
Status InitList(LinkList *L)
{
    *L=(LinkList)malloc(sizeof(Node)); /* 產生頭結點,並使L指向此頭結點 */
    if(!(*L)) /* 儲存分配失敗 */
        return ERROR;
    (*L)->next=NULL; /* 指標域為空 */

    return OK;
}

/* 初始條件:順序線性表L已存在。操作結果:返回L中資料元素個數 */
int ListLength(LinkList L)
{
    int i=0;
    LinkList p=L->next; /* p指向第一個結點 */
    while(p)
    {
        i++;
        p=p->next;
    }
    return i;
}

/* 初始條件:順序線性表L已存在 */
/* 操作結果:依次對L的每個資料元素輸出 */
Status ListTraverse(LinkList L)
{
    LinkList p=L->next;
    while(p)
    {
        visit(p->data);
        p=p->next;
    }
    printf("\n");
    return OK;
}

/*  隨機產生n個元素的值,建立帶表頭結點的單鏈線性表L(尾插法) */
void CreateListTail(LinkList *L, int n)
{
    LinkList p,r;
    int i;
    srand(time(0));                      /* 初始化隨機數種子 */
    *L = (LinkList)malloc(sizeof(Node)); /* L為整個線性表 */
    r=*L;                                /* r為指向尾部的結點 */
    for (i=0; i < n; i++)
    {
        p = (Node *)malloc(sizeof(Node)); /*  生成新結點 */
        p->data = rand()%100+1;           /*  隨機生成100以內的數字 */
        r->next=p;                        /* 將表尾終端結點的指標指向新結點 */
        r = p;                            /* 將當前的新結點定義為表尾終端結點 */
    }
    r->next = NULL;                       /* 表示當前連結串列結束 */
}

LinkList SelectSort2(LinkList L)
{
    LinkList p,q,small;
    int temp;

    for(p = L->next; p->next != NULL; p = p->next)
    {
        small = p;
        for(q = p->next; q; q = q->next)
        {
            if(q->data < small->data)
            {
                small = q;
            }
        }
        printf("迴圈後,獲得最小值為:%d, 此時連結串列為:", small->data);
        if(small != p)
        {
            temp = p->data;
            p->data = small->data;
            small->data = temp;
        }
        ListTraverse(L);
    }
    printf("輸出排序後的數字:\n");
    return L;
}

LinkList SelectSort(LinkList L)
{
    LinkList first;     /*排列後有序鏈的表頭指標*/
    LinkList tail;      /*排列後有序鏈的表尾指標*/
    LinkList p_min;     /*保留鍵值更小的節點的前驅節點的指標*/
    LinkList min;       /*儲存最小節點*/
    LinkList p;         /*當前比較的節點*/

    first = NULL;
    while (L != NULL) /*在連結串列中找鍵值最小的節點。*/
    {
        /*注意:這裡for語句就是體現選擇排序思想的地方*/
        for (p=L,min=L; p->next!=NULL; p=p->next) /*迴圈遍歷連結串列中的節點,找出此時最小的節點。*/
        {
            if (p->next->data < min->data) /*找到一個比當前min小的節點。*/
            {
                p_min = p; /*儲存找到節點的前驅節點:顯然p->next的前驅節點是p。*/
                min = p->next; /*儲存鍵值更小的節點。*/
            }
        }

        /*上面for語句結束後,就要做兩件事;
            一是把它放入有序連結串列中;
            二是根據相應的條件判斷,安排它離開原來的連結串列。*/

        /*第一件事*/
        if (first == NULL) /*如果有序連結串列目前還是一個空連結串列*/
        {
            first = min; /*第一次找到鍵值最小的節點。*/
            tail = min; /*注意:尾指標讓它指向最後的一個節點。*/
        }
        else /*有序連結串列中已經有節點*/
        {
            tail->next = min; /*把剛找到的最小節點放到最後,即讓尾指標的next指向它。*/
            tail = min; /*尾指標也要指向它。*/
        }
        /*第二件事*/
        if (min == L) /*如果找到的最小節點就是第一個節點*/
        {
            //printf("表頭%d已經是最小,當前結點後移。\n", min->data);
            L = L->next; /*顯然讓head指向原head->next,即第二個節點,就OK*/
        }
        else /*如果不是第一個節點*/
        {
            p_min->next = min->next; /*前次最小節點的next指向當前min的next,這樣就讓min離開了原連結串列。*/
        }
    }
    if (first != NULL) /*迴圈結束得到有序連結串列first*/
    {
        tail->next = NULL; /*單向連結串列的最後一個節點的next應該指向NULL*/
    }
    L = first;
    return L;
}

int main()
{
    LinkList L;
    Status i;
    char opp;
    ElemType e;
    int find;
    int tmp;

    i=InitList(&L);
    printf("初始化L後:ListLength(L)=%d\n",ListLength(L));

    printf("\n1.檢視連結串列 \n2.建立連結串列(尾插法) \n3.連結串列長度 \n4.交換兩個結點 \n0.退出 \n請選擇你的操作:\n");
    while(opp != '0')
    {
        scanf("%c",&opp);
        switch(opp)
        {
        case '1':
            ListTraverse(L);
            printf("\n");
            break;

        case '2':
            CreateListTail(&L,10);
            printf("整體建立L的元素(尾插法):\n");
            ListTraverse(L);
            printf("\n");
            break;

        case '3':
            //clearList(pHead);   //清空連結串列
            printf("ListLength(L)=%d \n",ListLength(L));
            printf("\n");
            break;

        case '4':
            L = SelectSort2(L);
            //printf("%d \n", find);
            ListTraverse(L);
            printf("\n");
            break;

        case '0':
            exit(0);
        }
    }
}

摘自:http://www.nowamagic.net/librarys/veda/detail/1852

相關推薦

單鏈排序選擇排序

單鏈表排序是單鏈表的常見程式設計任務之一,也是面試中經常出現的題目。單鏈表排序的關鍵是交換演算法,需要額外考慮。選擇排序是比較直觀的排序演算法之一,這裡就使用選擇排序實現單鏈表的排序。 LinkList SelectSort2(LinkList L) { Link

Java建立單鏈並直接選擇排序輸出

RT 寫Java也一年左右了,第一次用Java寫單鏈表。。。 廢話少說,程式碼如下: import java.util.Scanner; public class Exp1 { public s

真題2003 2016 單鏈的簡單選擇排序

題目:知單鏈表的結點結構為Data next 下列演算法對帶頭結點的單鏈表L進行簡單選擇排序,使得L中的元素按值從小到大排列。 (可用文字說明該演算法的基本思想及執行的過程,10分) 演算法思想:每趟找出一個最小的元素 void Select_Sort(Link

常用排序選擇排序

length stat sort simple out blog 一個 i++ string 算法簡介:      選擇排序就是每一趟選擇最小或者最大的數,然後與起始位置進行交換。 實現思路:      1、從第一個數開始,找到最小或者最大的數,與第一個數進行交換。

經典排序選擇排序

思想 space election 數據 穩定性 sys 存在 算法思想 oid 選擇排序(SelectionSort)的算法思想:對於n個待排序的數組,進行n-1次排序,每次選出待排序數據集中的最小數(或最大數),然後將選出的最小數(或最大數)與當前待排序數據集的首個數交

五 簡單排序選擇排序

++ http sta sel length [] blog post select 原理圖: 源代碼: public class selectionArray { public static void sort(int[] array) /

排序快排JS

index 而後 想是 其中 baidu lan tmp urn 部分 快速排序(Quicksort)是對冒泡排序的一種改進。   它的基本思想是:通過一趟排序將要排序的數據分割成獨立的兩部分,其中一部分的所有數據都比另外一部分的所有數據都要小,然後再按此方法對這兩部分數

Java 排序選擇排序、堆排序

三、選擇排序 1. 演算法簡介 選擇排序相對於上一篇文章記錄的插入排序、希爾排序要簡單一些,它比較直觀。它的基本思路為:把第一個元素依次和後面的所有元素進行比較,第一次結束後,就會有最小值出現在最前面,依次類推。 2. 演算法分析 假設有一個數組: int[]

經典排序選擇排序、插入排序、氣泡排序、希爾排序

選擇排序 void selectionSort(int arr[], int n) { for (int i = 0; i < n; i++) { int minIndex = i; // 記錄待排陣列中最小元素的下標 for (int j = i + 1; j < n;

連結串列排序選擇排序

選擇排序的優點在於它每次選擇出最大或者最小的值,將它們進行排序 此選擇排序的思想在於選擇出最小的節點,建立新連結串列,將原連結串列的最小節點刪除,繼續迴圈 TYPE* lain(int l, T

java陣列排序選擇排序

         基本思想:    在陣列中待排序的資料元素中選出最小(或最大)的一個元素,依次存放在序列的起始位置,直到全部待排序的資料元素排完。          操作:       給定一陣列     int [ ] arr = new int[ ]{34, 19,

java排序 選擇排序

基本原理: 1:給定的一組記錄,經過第一輪比較後得到最小的記錄,然後將該記錄與第一個記錄位置進行交換 2:接著對不包含的第一個記錄的以外的其他記錄進行第二輪比較,得到最小記錄並於第二個記錄進行位置交換; 3: 重複1,2 步 案例 :{38,55,69,

CSS3學習系列選擇

計算 選擇器 sky :focus ddr gree for 指定元素 學習 first-child選擇器和last-child選擇器 first-child指定第一個元素。last-child指定最後一個子元素。 例如: <!DOCTYPE html>

iOS 選擇Selector

1 前言     本文是一篇關於選擇器(Selector)的文章,Selector可以理解為一個方法名,具體見下文。 2 詳述     Selector是一個物件中用來選擇方法來執行的名字,或者是當原始碼編譯時候用來替換名字的唯一的標示。Selector自己並不

考研資料結構與演算法----單鏈的建立和讀取1

    先來個簡單的,晚上再把整表刪除神馬的加上,懶得註釋了,貼出來就是給同樣考研的同志們做個參考。     話說現在大學折騰的越來越水,當年我們學資料結構的時候單鏈表就算是五個實驗裡面第二難的了,最難的是一個二叉樹的,最後反正是都沒做出來直接往上抄的。其實現在回頭看過來倒

瘋狂ios講義選擇UIPickerView

UIPickerView也是一個選擇器控制元件,它比UIDatePicker更加通用,它可以生成單列的選擇器,也可生成多列的選擇器,而且開發者完全可以自定義選擇項的外觀,因此用法非常靈活。 UIPickerView直接繼承了UIView,沒有繼承UIControl,因此,它不能像UIControl那樣繫結

排序演算法選擇排序直接選擇、堆排序

排序演算法穩定性 假定在待排序的記錄序列中,存在多個具有相同的關鍵字的記錄,若經過排序,這些記錄的相對次序保持不變,即在原序列中,r[i]=r[j],且r[i]在r[j]之前,而在排序後的序列中,r[i]仍在r[j]之前,則稱這種排序演算法是穩定的;否則稱為不穩定的。 ————百度百

排序演算法選擇排序關鍵詞:資料結構/演算法/排序演算法/選擇排序

假定:有 1 個亂序的數列 nums ,其中有 n 個數。 要求:排好序之後是 從小到大 的順序。 選擇排序演算法 程式碼 from swap import swap def select_sort(nums): n = len(nums) i = 0 while

《資料結構與演算法》排序演算法氣泡排序選擇排序

排序(Sorting) 是計算機程式設計中的一種重要操作,它的功能是將一個數據元素(或記錄)的任意序列,重新排列成一個關鍵字有序的序列。 排序演算法分類: 一、非線性時間比較類排序 1、交換排序(氣泡排序、快速排序) 2、插入排序(簡單插入排序、布林排序) 3、選擇排序(簡單選擇

Java中的經典演算法選擇排序SelectionSort

Java中的經典演算法之選擇排序(SelectionSort) 神話丿小王子的部落格主頁 a) 原理:每一趟從待排序的記錄中選出最小的元素,順序放在已排好序的序列最後,直到全部記錄排序完畢。也就是:每一趟在n-i+1(i=1,2,…n-1)個記錄中選取關鍵字最小的記錄作為有序序列中第i個記錄。基