一、表插入排序优点
为了减少在排序过程中进行的“移动”记录的操作,必须改变排序过程中采用的存储结构。利用静态链表进行排序,并在排序完成之后,一次性的调整各个记录相互之间的位置,即将在各个记录都调整到它们所应该在的位置。
二、表结构
type Node struct{
value int
next int
}
var NL []Node //NL为此记录表
表结构就是一个静态链表,它可以用一个数组来初始化,初始化用头元素和第一个元素组成一个循环链表,然后排序时从第二个元素开始插入到这个循环链表中,当然只是修改每个元素的next域。使头结点的next域始终指示最小的那个元素,然后依次向下:每一个元素的next域都指示比它稍大的那个元素。最大的元素的next域指示头结点。这样形成一个循环链表。
三、过程:
1、用数组初始化表结构。
2、修改next域形成有序的循环链表。
3、根据next域信息调整表结构中的数组,是数据从小到大排列。
四、详细过程
1、用数组初始化表结构
代码如下:
func InitList(a []int){
var node Node
node = Node{INT_MAX,1}
NL = append(NL,node)
for i:=1;i<=len(a);i++ {
node = Node{a[i-1],0}
NL = append(NL,node)
}
//fmt.Println(NL)
}
2、修改next域形成有序的循环链表
func ListSort() {
var i,low,high int
for i=2;i<len(NL);i++ {
low=0 //初始化low:0, high:1
high=NL[0].next
for NL[high].value < NL[i].value { //寻找两个相邻的比NL[i]大的NL[max]和比NL[i]小的NL[min],插入之间
low=high
high=NL[high].next
}
NL[low].next = i //插入之间
NL[i].next = high
}
//fmt.Println(NL)
}
3、根据next域调整数组,使数组有序
完成插入排序之后,需要调整指针域的值,指针值p一直next,i从1到7一直加,将指针值指的值放入i区域。
i:第i个记录应该放在的位置 p:第i个记录的当前位置 q:第i+1个记录的当前位置
i表示此次调整要放入的位置,p指向现在要放入i中的值,q指向下次要放入i+1中的值
调整步骤如下:
1)将i与p对应的记录进行交换(i的指针值不用变化)
2)将i对应的指针值改为原来在i处的值搬家搬去的地方,1的值换到了6,所以1处的指针值为6
第一次调整:
结果:
现在q变成了p,q本来为p的next,但p指向的1<i(1是已经排好的,所有继续next),结果q为如下所示
重复上面过程,直到i==len(NL)-1
代码:
func Arrange(){
p := NL[0].next //p指示第一个记录的当前位置,即还没有排序的最小值
for i:=1;i< len(NL);i++ {
for p<i { //i之前的都是排好的
p = NL[p].next
}
q := NL[p].next //下一个要排序的记录,p排好就到q了,找第i+1个记录做准备
if p != i { //交换记录,使第i个记录到位
NL[p].value,NL[i].value = NL[i].value,NL[p].value
NL[p].next = NL[i].next
NL[i].next = p //指向被移走的记录(搬家的记录)
}
p = q //找第i+1个记录做准备
}
//fmt.Println(NL)
for i:=1;i< len(NL);i++ {
fmt.Printf("%d ",NL[i].value)
}//结果:11 17 28 36 44 53 62
}
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
最终结果:
五、全部代码:
const INT_MAX = int(^uint(0) >> 1)
type Node struct{
value int
next int
}
var NL []Node
func InitList(a []int){
var node Node
node = Node{INT_MAX,1}
NL = append(NL,node)
for i:=1;i<=len(a);i++ {
node = Node{a[i-1],0}
NL = append(NL,node)
}
//fmt.Println(NL)
}
func ListSort() {
var i,low,high int
for i=2;i<len(NL);i++ {
low=0 //初始化low:0, high:1
high=NL[0].next
for NL[high].value < NL[i].value { //寻找两个相邻的比NL[i]大的NL[max]和比NL[i]小的NL[min],插入之间
low=high
high=NL[high].next
}
NL[low].next = i //插入之间
NL[i].next = high
}
//fmt.Println(NL)
}
func Arrange(){
p := NL[0].next //p指示第一个记录的当前位置,即还没有排序的最小值
for i:=1;i< len(NL);i++ {
for p<i { //i之前的都是排好的
p = NL[p].next
}
q := NL[p].next //下一个要排序的记录,p排好就到q了,找第i+1个记录做准备
if p != i { //交换记录,使第i个记录到位
NL[p].value,NL[i].value = NL[i].value,NL[p].value
NL[p].next = NL[i].next
NL[i].next = p //指向被移走的记录(搬家的记录)
}
p = q //找第i+1个记录做准备
}
//fmt.Println(NL)
for i:=1;i< len(NL);i++ {
fmt.Printf("%d ",NL[i].value)
}//结果:11 17 28 36 44 53 62
}
func main(){
a := []int{28,62,17,36,53,11,44}
InitList(a)
ListSort()
Arrange()
//结果:11 17 28 36 44 53 62
}