zoukankan      html  css  js  c++  java
  • 【排序】表插入排序算法(C语言版)

    排序耗时的操作主要分为两种:查找比较、记录移位。


    1.表插入排序

    在查找比较基础上,尽量减少记录移位步数,可以令排序操作耗时降低,表插入排序正是为减少移位次数而出现的。

    在数据结构上,数据是存储在静态数组(表)中,而每个数组除了数据关键字外还记录了表中下一个记录,按记录遍历的关键字则是排序的结果。

    如:有如下需要排序的数据: 

    关键字 5 1 3 2 4
    下一个记录的表中位置 - - - - -

    排序后得到的表为

    关键字 5 1 3 2 4
    下一个记录的表中位置 -1 3 4 2 0

    这里还需要提到重排记录的方法:

    由于重排过程中,需要移动记录的位置,所以"下一个记录的表中位置"则会产生变化,而又因为重排过程中表中不同数据只会被访问一次,所以可以利用失效的"下一个记录的表中位置"记录未被访问的数据且因重排被移位的新位置。

    重排时,以i记录已经排好的记录数量,p记录要重拍的关键字,如果p<i,表示要重拍的关键字被移位了,所以再获取表中的"下一个记录的表中位置"即可。

    #include <stdio.h>
    #include <stdlib.h>
    
    typedef struct{
    	int data;
    	int next;
    }node;
    typedef struct{
    	node *list;
    	int head;
    }table;
    
    int main(void){
    	node *s;
    	int cnt=0, k, cntmax=10, nexttemp, datatemp, kk;
    	int head, preindex;
    	int p,i;
    	table mytable;
    
    	s = (node*)malloc(sizeof(node)*10);
    	while(1){
    		scanf("%d", &datatemp);
    		if(datatemp<0)
    			break;
    		(s+cnt)->data = datatemp;
    		cnt++;
    		if(cnt==cntmax){
    			s = (node*)realloc(s, cntmax+10);
    			cntmax += 10;
    		}
    	}
    	mytable.list = s;
    
    	head = 0;
    	s->next = -1; //-1表示链表表尾结点
    	//表插入排序
    	for(k=1; k<cnt; k++){
    		kk=head;
    		while(kk!=-1){		
    			if((s+kk)->data>(s+k)->data){
    				if(kk==head){
    					head = k;
    					(s+k)->next = kk;
    				}
    				else{
    					(s+preindex)->next = k;
    					(s+k)->next = kk;
    				}
    				break;
    			}
    			else{
    				preindex = kk;
    				kk = (s+kk)->next;			
    			}
    		}
    		if(kk==-1){
    			(s+preindex)->next = k;
    			(s+k)->next = -1;
    		}
    	}
    	mytable.head = head;
    
    	for(k=mytable.head; k!=-1; k=(mytable.list+k)->next){
    		printf("%d ", (mytable.list+k)->data);
    	}
    	printf("
    ");
    
    	//记录重排-->这里是难点~~
    	for(i=0, p=head; i<cnt; i++){
    		//i位置结点与k位置结点交换
    		while(p<i)  //----->注意这里哟,逐个找回来
    			p = (s+p)->next;
    		k = (s+p)->next;  //保存指向的下一个需要重排的关键字位置
    
    		if(p!=i){
    			datatemp = (s+p)->data;
    			nexttemp = (s+p)->next;
    			(s+p)->data = (s+i)->data;
    			(s+p)->next = (s+i)->next;
    			(s+i)->data = datatemp;
    			(s+i)->next = p;
    		}
    
    		p = k;
    	}
    	for(i=0; i<cnt; i++){
    		printf("%d ", (mytable.list+i)->data);
    	}
    	printf("
    ");
    
    	system("pause");
    	return 0;
    }

    其他排序请见后篇

  • 相关阅读:
    UIApplication直接应用
    iOS开发之苹果开发者账号注册申请流程
    iOS开发之蓝牙使用-建立连接的
    Swift3.0 UICollectionView简单使用
    CSS网页菜单
    c#qq发邮件
    多文档界面的实现(DotNetBar的superTabControl)
    CE修改器:外挂制作高级技巧
    MariaDB 库的基本操作
    Python-使用PyQT生成图形界面
  • 原文地址:https://www.cnblogs.com/xhyzjiji/p/6159374.html
Copyright © 2011-2022 走看看