排序演算法----基數排序(RadixSort(L,max))單鏈表版本

来源:http://www.cnblogs.com/xinlovedai/archive/2016/12/26/6223855.html
-Advertisement-
Play Games

轉載http://blog.csdn.net/Shayabean_/article/details/44885917博客 先說說基數排序的思想: 基數排序是非比較型的排序演算法,其原理是將整數按位數切割成不同的數字,然後按每個位數分別比較。 將所有待比較數值(正整數)統一為同樣的數位長度,數位較短的數 ...


轉載http://blog.csdn.net/Shayabean_/article/details/44885917博客

先說說基數排序的思想:   

基數排序是非比較型的排序演算法,其原理是將整數按位數切割成不同的數字,然後按每個位數分別比較。

 

將所有待比較數值(正整數)統一為同樣的數位長度,數位較短的數前面補零。然後,從最低位開始,依次進行一次排序。在每一次排序中,按照當前位把數組元素放到對應        

的桶當中,然後把桶0到桶9中的元素按先進先出的方式放回數組中。這樣從最低位排序一直到最高位排序完成以後, 數列就變成一個有序序列。

 

這個版本的基數排序RadixSort(L,max)較RadixSort(L)不同的是需要輸入待排序列最大數的位數。因為RadixSort(L)最大數位在程式中已經計算過了,因為需要計算最大數,所以需要對待排鏈表最開始迴圈一次,所以RadixSort(L,max)速度比RadixSort(L)稍快。

這篇博客包括4個文件,兩個頭文件RadixSort.h和fatal.h,一個庫函數RadixSort.c,和一個測試文件Test_Radix_Sort.c

頭文件fatal.h:

1 #include<stdio.h>
2 #include<stdlib.h>
3 #define Error(Str) FatalError(Str)
4 #define FatalError(Str) fprintf(stderr, "%s\n", Str), exit(1);

頭文件RadixSort.h

 1 typedef int ElementType;
 2 #ifndef RADIX_SORT_H
 3 #define RADIX_SORT_H
 4 
 5 #include<stdbool.h>
 6 #define ListEmpty -2
 7 
 8 struct Node;
 9 typedef struct Node *PtrToNode;
10 typedef PtrToNode List;
11 typedef PtrToNode Position;
12 
13 List MakeEmpty(List L);
14 bool IsEmpty(List L);
15 bool IsLast(Position P, List L);
16 Position Header(List L);
17 Position Advance(Position P);
18 ElementType Retrieve(Position P);
19 void DeleteList(List L);
20 void PrintList(const List L);
21 void Insert(ElementType X, List L, Position P);
22 void MoveNode(List L1, List L2);//將表L2中的頭節點移動成為L1的尾節點
23 void RadixSort(List L,int max);//最終基數排序函數,輸入鏈表L,將L排序得到新的排序鏈表L,其中max是待排元素最高有多少位
24 #endif // !RADIX_SORT_H

 

其中RadixSort是最終排序函數,調用它即可排序。

庫函數RadixSort.c

  1 #include "RadixSort.h"
  2 #include<stdio.h>
  3 #include<stdlib.h>
  4 #include<malloc.h>
  5 #include<math.h>
  6 #include"fatal.h"
  7 struct Node
  8 {
  9     ElementType Element;
 10     Position Next;
 11 };
 12 
 13 //初始化鏈表
 14 List MakeEmpty(List L)
 15 {
 16     if (L != NULL)
 17         DeleteList(L);//如果鏈表非空,則刪除鏈表
 18     L = malloc(sizeof(struct Node));
 19     if (L == NULL)
 20         FatalError("Out of memory!");
 21     L->Next = NULL;
 22     return L;
 23 }
 24 //判斷鏈表是否為空
 25 bool IsEmpty(List L)
 26 {
 27     return L->Next == NULL;
 28 }
 29 
 30 //判斷當前指針P是否指向鏈表最後一個元素
 31 bool IsLast(Position P, List L)
 32 {
 33     return P->Next == NULL;
 34 }
 35 
 36 //獲取鏈表頭
 37 Position Header(List L)
 38 {
 39     return L;
 40 }
 41 
 42 //獲取位置P的下一個位置
 43 Position Advance(Position P)
 44 {
 45     return P->Next;
 46 }
 47 
 48 //提取位置P處結構裡面的值
 49 ElementType Retrieve(Position P)
 50 {
 51     return P->Element;
 52 }
 53 
 54 //刪除鏈表
 55 void DeleteList(List L)
 56 {
 57     Position P, Temp;
 58     P = L->Next;
 59     L->Next = NULL;
 60     while (P != NULL)
 61     {
 62         Temp = P->Next;
 63         free(P);
 64         P = Temp;
 65     }
 66 }
 67 
 68 //列印鏈表
 69 void PrintList(const List L)
 70 {
 71     Position P = Header(L);
 72     if (IsEmpty(L))
 73         printf("Empty list\n");
 74     else
 75     {
 76         do
 77         {
 78             P = Advance(P);
 79             printf("%d ", Retrieve(P));
 80         } while (!IsLast(P, L));
 81         printf("\n");
 82     }
 83 }
 84 
 85 //插入元素X到位置P後面
 86 void Insert(ElementType X, List L, Position P)
 87 {
 88     Position  TmpCell;
 89     TmpCell = malloc(sizeof(struct Node));
 90     if (TmpCell == NULL)
 91         FatalError("Out of Space!!!");
 92     TmpCell->Element = X;
 93     TmpCell->Next = P->Next;
 94     P->Next = TmpCell;
 95 }
 96 
 97 void MoveNode(List L1, List L2)
 98 {
 99     //將表L2中的頭節點移動成為L1的尾節點 
100     Position Tmp1 = L1;
101     Position Tmp2;
102     if (IsEmpty(L2)) exit(ListEmpty);
103     while (!IsLast(Tmp1,L1))
104         Tmp1 = Tmp1->Next;//使Tmp1指向L1表尾 
105     Tmp2 = L2->Next;
106     L2->Next = Tmp2->Next;
107     Tmp1->Next = Tmp2;
108     Tmp2->Next = NULL;    
109 }
110 
111 void RadixSort(List L,int max)
112 {
113     //if (IsEmpty(L)) return L; //如果要排序的鏈表L是空表,則不排序
114     int i,j, TmpSub;//Tmpsub存儲數的個位、十位、百位
115     ElementType FirstElement;//存儲鏈表的第一個元素
116 
117     List Bucket[10];//開闢10個桶,依次為0~9
118     for (i = 0; i < 10; i++) Bucket[i] = MakeEmpty(NULL);//對10桶進行初始化,每一個數組都是一個鏈表
119     for (i = 0; i < max; i++)//開始提取每一位數的個位、十位、百位
120     {
121         while (!IsEmpty(L))//當L中的元素被取光了,則迴圈結束
122         {
123             FirstElement = L->Next->Element;//取出第一個節點的數據
124             TmpSub = (int)(FirstElement / pow(10, i)) % 10;//依次取出個十百位數字 
125             MoveNode(Bucket[TmpSub], L);//將L中的節點依次移到對應的桶中
126         }
127         for (j = 0; j < 10; j++)    //將桶中的數再次移動到L中
128         {
129             while (!IsEmpty(Bucket[j])) MoveNode(L, Bucket[j]);
130         }
131     }
132     for (i = 0; i < 10; i++) free(Bucket[i]) ;//釋放掉10個桶
133 }

測試函數Test_Radix_Sort.c

 1 #include<stdio.h>
 2 #include "RadixSort.h"
 3 #include"fatal.h"
 4 #include<time.h>
 5 
 6 int main()
 7 {
 8     int  amount;10     List L; Position P;
11     L = MakeEmpty(NULL);//初始化鏈表
12     P = L;
13     if (L == NULL) Error("Out of Space!!!");
14     printf("隨機生成多少位數:");
15     scanf_s("%d", &amount);
16     srand((unsigned)time(NULL));
17     for (int i = 0; i < amount; i++)
18     {
19         Insert(rand() % 10000, L, P);
20         P = Advance(P);
21     }
22     printf("排序前的結果:");
23     PrintList(L);
24     RadixSort(L,4);//調用排序函數排序
25     printf("基數排序後的結果:");
26     PrintList(L);
27 }


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 這個類在日常的開發中,還是非常常用的。今天就總結一下Arrays工具類的常用方法。最常用的就是asList,sort,toStream,equals,copyOf了。另外可以深入學習下Arrays的排序演算法,這個還是非常有用的。 所有的方法都是在下麵的類中進行測試的: asList 這個方法可以把數 ...
  • 目的: 使用垃圾回收器的唯一原因就是:回收程式不再使用的記憶體。 針對的目標對象: Java的垃圾回收器會自動回收不再使用的Java對象,釋放記憶體。但是回收的是用new創建的,分配在堆上的記憶體。 finalize(): 那麼,如果不是用這種方式創建的對象,該怎麼回收?比如:Java調用了本地的c語言方 ...
  • 今天在看別人代碼時看到這樣一種寫法, 感覺是個挺容易踩到的坑, 搞清楚後寫出來備忘. 短路邏輯 Python中進行邏輯運算的時候, 預設採用的是一種叫做短路邏輯的運算規則. 名字是很形象的, 下麵直接看代碼 可以看到, 雖然1會被當做布爾值計算, 但整個表達式的計算結果卻不一定是布爾值, 而是根據表 ...
  • 現在的資料庫越來越多,如mgdb,我比較常用的是mysql,但有一天做項目需要連接SqlServer,就去找了個方法。找了很多無非就mssql模塊和node-sqlserver模塊,但node-sqlserver好像有很多限制和還要編譯,感覺很麻煩,就用了mssql模塊。mssql模塊還是很簡單的, ...
  • 一般的智能指針都是通過一個普通指針來初始化,所以很容易寫出以下的代碼: #include using namespace std; int func1(){ //返回一個整數的函數 } void func2(AutoPtr ptr,int t){ //一些操作 } int ... ...
  • (1)、編寫配置文件 Hibernate通過讀寫預設的XML配置文件hibernate.cfg.xml載入資料庫配置信息、代碼如下: (2)、編寫持久化類 持久化類是Hibernate操作的對象、它與資料庫中的數據表相對應 (3)、編寫映射文件 (4)、編寫Hibernate的工具類 ...
  • 下期預告,函數... ...
  • 題目大意:給定一個長度為n的整數序列x[i],確定一個二元組(b, k)使得S=Σ(k*i+b- x[i])^2(i∈[0,n-1])最小 看Claris大神的題解就行了。實際上就是用2次二次函數的性質。 http://www.cnblogs.com/clrs97/p/4703437.html 代碼 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...