排序思想
属于插入排序的一种,法如其名:先找到正确的插入位置,然后把该位置后面的元素依次后移,最后插入新元素。
排序特点
稳定排序算法
空间复杂度:O(1)
时间复杂度:最好O(n);平均O(n2);最坏O(n2)
如果数据已经基本有序,那么选择直接插入排序是很明智的(因为这样可以节省比较和移动的次数)
数组存储
也就是存储结构采用线性表中的顺序表 。
数据结构
一个普通数组。
int arr[] = { 9, 6, 8, 5, 7, 2, 0, 3, 1, 4};
核心代码
void Sort(int arr[], int len)
{
if(len>0)
{
for (int i = 0; i < len-1; i++)
{
int M = i;
int num = arr[i + 1];
if (M >= 0)
{
//从有序表的最后开始找到第一个小于num的合法点
while (num < arr[M])
{
arr[M + 1] = arr[M];
M--;
}
}
arr[M + 1] = num;
for (int i = 0; i < 10; i++)
printf("%d ", arr[i]);
printf("\n");
}
}
}
运行输出
链表存储
也就是存储结构采用线性表中的链表 。
数据结构
一个普通结点结构体。
typedef int ElemType;
typedef struct LNode
{
ElemType data;
struct LNode* next;
}LNode, *LinkList;
核心代码
带有头结点的单链表。
void Sort(LinkList &L)
{
LNode *pnow, *pnext, *pre, *prepre;
if (L->next != NULL)
{
pnow = L->next->next;
L->next->next = NULL;
while (pnow != NULL)
{
//从头开始找到第一个大于p的data的非空结点q
prepre = L;
pre = prepre->next;
while (pre != NULL&&pre->data < pnow->data)
{
prepre = pre;
pre = pre->next;
}
//确定下一个要排序的结点
pnext = pnow->next;
//交换p和q
pnow->next = pre;
prepre->next = pnow;
//马不停蹄开始决策下一个
pnow = pnext;
Display(L);
}
}
}
运行输出
最后小结
顺序表和链表是两种不同的存储结构(直接插入排序算法属于逻辑),所以会有所区别,主要体现在:
数组是:正式开始排序之前所有的待排数据按照已给顺序存放在一个数组里。
链表是:正式开始排序之前借助尾插法把所有的待排数据按照已给顺序放在一个链表里。
数组是:从第二个元素开始排序,从当前要排的数据开始,从后向前比较,如果前面的元素大,那么就把它移后一个,直到找到第一个比自己小的,插入到这个数据后面(所以需要M和num)。
链表是:从第二个元素开始排序,从链表第一个数据开始,从前向后比较,如果后面的元素小,那么指针就移后一个,直到找到第一个比自己大的,插入到这个数据前面(所以需要*pre 和 *prepre)。