golang ------------ 表插入排序

一、表插入排序优点

为了减少在排序过程中进行的“移动”记录的操作,必须改变排序过程中采用的存储结构。利用静态链表进行排序,并在排序完成之后,一次性的调整各个记录相互之间的位置,即将在各个记录都调整到它们所应该在的位置。

二、表结构

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
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值