【筆記】表插入排序
插入排序:將待排序元素分為已排序子集和未排序子集,一次從未排序子集中的一個元素插入已排序子集中,使已排序自己仍然有序;重複執行以上過程,指導所有元素都有序為止。
#define SIZE 100 /* 靜態連結串列容量 */
typedef int KeyType; /* 定義關鍵字型別為整型 */
typedef struct
{
KeyType key; /* 關鍵字項 */
InfoType otherinfo; /* 其它資料項,具體型別在主程中定義 */
}RedType; /* 記錄型別 */
typedef struct
{
RedType rc; /* 記錄項 */
int next; /* 指標項 */
}SLNode; /* 表結點型別 */
typedef struct
{
SLNode r[SIZE]; /* 0號單元為表頭結點 */
int length; /* 連結串列當前長度 */
}SLinkListType; /* 靜態連結串列型別 */
基本演算法思想:假設以上述說明的靜態連結串列型別作為待排記錄序列的儲存結構,並且為了插入方便起見,設陣列中下標為0的分量為表頭結點,並令表頭結點記錄的關鍵字取最大整數MAXINT。則表插入排序的過程描述如下:首先將靜態連結串列中陣列下標為1的分量和表頭結點構成一個迴圈連結串列,然後依次將下標為2至n的分量(結點)按記錄關鍵字非遞減有序插入到迴圈連結串列中。
以序列(49,38,65,97,76,13,27,49)為例,表插入排序的過程如下圖所示。
從表插入排序的過程可見,表插入排序的基本操作仍是將一個記錄插入到已排好序的有序表中。和直接插入排序相比,不同之處僅是修改2n次指標值代替移動記錄,排序過程中所需進行的關鍵字間的比較次數相同。因此表插入排序的時間複雜度仍是
表插入排序的結果只是求得一個有序連結串列,則只能對它進行順序查詢,不能進行隨機查詢,為了能實現有序表的折半查詢,尚需對記錄進行重新排列。
重排記錄的做法:順序掃描有序連結串列,將連結串列中的第i個結點移動至陣列的第i個分量中。如下圖所示,(a)是經表插入排序後得到的有序連結串列SL。根據頭結點中指標域的指示,連結串列的第一個結點,即關鍵字最小的結點是陣列中下標為6的分量,其中記錄應移動至陣列的第一個分量中,則將SL.r[1]和SL.r[6]互換,並且為了不中斷靜態連結串列中的鏈,即在繼續順鏈掃描時仍能找到互換之前在SL.r[1]中的結點,令互換之後的SL.r[1]中指標域的值修改為6。推廣至一般情況,若第i個最小關鍵字的結點是陣列中下標為
- 標頭檔案
#define MAXSIZE 20 /* 一個用作示例的小順序表的最大長度 */
typedef int InfoType; /* 定義其它資料項的型別 */
typedef int KeyType; /* 定義關鍵字型別為整型 */
typedef struct
{
KeyType key; /* 關鍵字項 */
InfoType otherinfo; /* 其它資料項,具體型別在主程中定義 */
}RedType; /* 記錄型別 */
typedef struct
{
RedType r[MAXSIZE+1]; /* r[0]閒置或用作哨兵單元 */
int length; /* 順序表長度 */
}SqList; /* 順序表型別 */
- 函式檔案
void TableInsert(SLinkListType *SL,RedType D[],int n)
{ /* 由陣列D建立n個元素的表插入排序的靜態連結串列SL */
int i,p,q;
(*SL).r[0].rc.key=INT_MAX; /* 表頭結點記錄的關鍵字取最大整數(非降序連結串列的表尾) */
(*SL).r[0].next=0; /* next域為0表示表尾(現為空表,初始化) */
for(i=0;i<n;i++)
{
(*SL).r[i+1].rc=D[i]; /* 將陣列D的值賦給靜態連結串列SL */
q=0;
p=(*SL).r[0].next;
while((*SL).r[p].rc.key<=(*SL).r[i+1].rc.key)
{ /* 靜態連結串列向後移 */
q=p;
p=(*SL).r[p].next;
}
(*SL).r[i+1].next=p; /* 將當前記錄插入靜態連結串列 */
(*SL).r[q].next=i+1;
}
(*SL).length=n;
}
void Arrange(SLinkListType *SL)
{ /* 根據靜態連結串列SL中各結點的指標值調整記錄位置,使得SL中記錄按關鍵字 */
/* 非遞減有序順序排列 */
int i,p,q;
SLNode t;
p=(*SL).r[0].next; /* p指示第一個記錄的當前位置 */
for(i=1;i<(*SL).length;++i)
{ /* (*SL).r[1..i-1]中記錄已按關鍵字有序排列,第i個記錄在SL中的當前位置應不小於i */
while(p<i)
p=(*SL).r[p].next; /* 找到第i個記錄,並用p指示其在SL中當前位置 */
q=(*SL).r[p].next; /* q指示尚未調整的表尾 */
if(p!=i)
{
t=(*SL).r[p]; /* 交換記錄,使第i個記錄到位 */
(*SL).r[p]=(*SL).r[i];
(*SL).r[i]=t;
(*SL).r[i].next=p; /* 指向被移走的記錄,使得以後可由while迴圈找回 */
}
p=q; /* p指示尚未調整的表尾,為找第i+1個記錄作準備 */
}
}
void Sort(SLinkListType L,int adr[])
{ /* 求得adr[1..L.length],adr[i]為靜態連結串列L的第i個最小記錄的序號 */
int i=1,p=L.r[0].next;
while(p)
{
adr[i++]=p;
p=L.r[p].next;
}
}
void Rearrange(SLinkListType *L,int adr[])
{ /* adr給出靜態連結串列L的有序次序,即L.r[adr[i]]是第i小的記錄。 */
/* 按adr重排L.r,使其有序. */
int i,j,k;
for(i=1;i<(*L).length;++i)
if(adr[i]!=i)
{
j=i;
(*L).r[0]=(*L).r[i]; /* 暫存記錄(*L).r[i] */
while(adr[j]!=i)
{ /* 調整(*L).r[adr[j]]的記錄到位直到adr[j]=i為止 */
k=adr[j];
(*L).r[j]=(*L).r[k];
adr[j]=j;
j=k; /* 記錄按序到位 */
}
(*L).r[j]=(*L).r[0];
adr[j]=j;
}
}
void print(SLinkListType L)
{
int i;
for(i=1;i<=L.length;i++)
printf("key=%d ord=%d next=%d\n",L.r[i].rc.key,L.r[i].rc.otherinfo,L.r[i].next);
}
- 主程式
#include<limits.h>
#define N 8
void main()
{
RedType d[N]={{49,1},{38,2},{65,3},{97,4},{76,5},{13,6},{27,7},{49,8}};
SLinkListType l1,l2;
int *adr,i;
TableInsert(&l1,d,N);
l2=l1; /* 複製靜態連結串列l2與l1相同 */
printf("排序前:\n");
print(l1);
Arrange(&l1);
printf("l1排序後:\n");
print(l1);
adr=(int*)malloc((l2.length+1)*sizeof(int));
Sort(l2,adr);
for(i=1;i<=l2.length;i++)
printf("adr[%d]=%d ",i,adr[i]);
printf("\n");
Rearrange(&l2,adr);
printf("l2排序後:\n");
print(l2);
}
- 測試結果
相關文章
- 雜湊表hashtable課堂筆記筆記
- Flutter學習筆記(13)--表單元件Flutter筆記元件
- 線性表__資料結構筆記資料結構筆記
- mysql修改表欄位學習筆記MySql筆記
- hive學習筆記之三:內部表和外部表Hive筆記
- hive學習筆記之四:分割槽表Hive筆記
- 資料結構筆記——線性表(下)資料結構筆記
- 資料結構筆記——線性表(中)資料結構筆記
- 三種插入排序 直接插入排序,折半插入排序,希爾排序排序
- 插入排序排序
- 手寫演算法並記住它:插入排序演算法排序
- 力扣刷題筆記:207. 課程表力扣筆記
- 資料庫學習筆記之查詢表資料庫筆記
- <react學習筆記(9)>表單控制元件React筆記控制元件
- CSS 小結筆記之三種樣式表CSS筆記
- 【閱讀筆記:雜湊表】Javascript任何物件都是一個雜湊表(hash表)!筆記JavaScript物件
- 03 插入排序排序
- python插入排序Python排序
- 插入排序排序排序
- GeoServer學習筆記-2、基本使用(釋出PostGIS表)Server筆記
- 筆記.財務報表分析.第1-2章筆記
- 印象筆記 --- 方法分享筆記筆記
- 如何理解插入排序?排序
- 插入排序(Insertion Sort)排序
- 插入排序-by-Python排序Python
- vue 基礎入門筆記 14:發表評論 demoVue筆記
- Vue.js 2.x筆記:表單繫結(3)Vue.js筆記
- EntityFramework Core筆記:表結構及資料基本操作(2)Framework筆記
- 《CSS重構:樣式表效能調優》讀書筆記CSS筆記
- 筆記筆記
- Mit6.S081筆記Lab3: page tables 頁表MIT筆記
- MySQL複習筆記(05):MySQL表級鎖和行級鎖MySql筆記
- JavaScript實現:插入排序!!!JavaScript排序
- 直接插入排序排序
- 插入排序以及優化排序優化
- 連結串列-插入排序排序
- 《演算法筆記二》連結串列、棧、佇列、遞迴、雜湊表、順序表演算法筆記佇列遞迴
- 【跟著阿舜學音樂-筆記】1.11和絃的表現形式筆記
- 資料庫課程作業筆記 - 編寫表單驗證資料庫筆記