八大排序算法中,最著名的就是插入排序,包含直接插入排序和希尔排序。直接插入排序较为简单,思想类似于我们打扑克牌的时候要将一张张纸牌按顺序梳理好,如果发现某张纸牌的的位置不正确,则直接将这张纸牌插入到正确的位置即可。
直接插入排序(按照由小到大的顺序排列)的解题思路:
1、将第一张纸牌(数据)默认为有序,将其插入到list列表
2、对于第二张及以后的纸牌,与list列表中的数据进行比较,如果找到合适的位置插入(合适的位置指比前一个数据大比后一个数据小的位置)
在数据结构中我们曾学习过,对于涉及到添加或者删除的操作,链表最适合,因此本次操作使用链表进行数据存储。
具体代码见下面,在这里我们整理一下使用链表进行操作的思路。
原材料:含有若干个无序的数字的一个数组
1、首先是创建初一个函数init()用于节点的初始化
2、然后创建一个函数funcInsert()用于将某个数字插入到链表中的正确位置
3、然后是打印整个链表
要注意的是:
1、funcInsert()函数中的插入思路:
A、如果是第一个数据,则直接插入到链表中
B、如果第二个及以后的数据num,就去遍历判断该数据跟排好序的链表集合中元素的关系,如果找到一个元素,它的下一个元素比num 大(第一次出现的),则将num插入到该元素后面(当然也可能存在某个num比链表中所有的元素都小,只要p->next->data是大于num的,就可以把num插入到p的后面)。如果遍历玩所有的都没有找到,则num是list中最大的元素,直接插入到节点最后面即可。
2、稳定性
由于在插入数字时将插入在p,其中p的下一个的数据是大于num的,所以是稳定的,举个栗子,如果插入49 56 49这三个数,在第二次插入49时,会插入到56 的前面,(链表中已经存储了49 56这个有序结构,所以只能是49的后面)所以是稳定的
<pre name="code" class="cpp">#include <stdio.h>
#include <stdlib.h>
#include<malloc.h>
typedef struct node{
int data;
struct node *next;
}Node,*PNode;
//初始化节点
PNode init()
{
PNode p = (PNode)malloc(sizeof(Node));
p->data = NULL;
p->next = NULL;
return p;
}
//将元素插入到其对应位置
void funcInsert(PNode p,int value)
{
PNode q = (PNode)malloc(sizeof(Node));
if(!q)
{
//printf("动态内存分配失败,程序退出\n");
exit(-1);
}
q->data = value;
q->next = NULL;
//1:如果是第一个插入的元素,则直接是第一号位置
if(p->next == NULL)
{
q->next = p->next;
p->next = q;
//printf("1:%d元素插入成功\n",value);
return;
}
else
{
//3:如果是第二个及以后的元素,则要找准正确的位置进行插入,
int count = 1;
while(p->next != NULL)
{
//printf("第一个元素:%d\n",p->next->data);
//只有满足该元素小于p->next->data的时候,才能插入在p的后面
if(value < p->next->data)
{
//printf("3->0:第%d大的元素%d插入成功,插入在%d前面\n",count,value,p->next->data);
q->next = p->next;
p->next = q;
return;
}
p = p->next;
count ++;
}
//printf("3->2:最大的元素%d插入成功,插入在%d后面\n",value,p->data);
q->next = p->next;
p->next = q;
}
}
//结果展示
void showList(PNode p)
{
while(p->next != NULL){
PNode t = p->next;
printf("%d\n",t->data);
p = p->next;
}
}
int main()
{
int list[11] = {49,38,65,97,76,13,27,49,7,-1,-1};
PNode p = init();
int i=0;
for(i=0;i<11;i++)
{
funcInsert(p,list[i]);
}
showList(p);
return 0;
}