关键词不能为空

当前您在: 主页 > 英语 >

SMART算法总结

作者:高考题库网
来源:https://www.bjmy2z.cn/gaokao
2021-02-01 21:24
tags:

-

2021年2月1日发(作者:alluvial)


SMART


算法总结



2011-09-20 12:01:17


我来说两句




收藏



我要投稿



排序算法有很多,所以在特 定情景中使用哪一种算法很重要。为了选择合适的算法,可以按照建议的顺序考虑以下标准:



1


)执行时间




2


)存储空间




3


)编程工作



对于数据量较小的情形,(


1


)(


2


)差别不大,主要考虑(

< p>
3


);而对于数据量大的,(


1

< br>)为首要。




主要排序法有:



一、冒泡(


Bubble


)排序——相邻交换



二、选择排序——每次最小


/


大排在相应的位 置



三、插入排序——将下一个插入已排好的序列中


< p>
四、壳(


Shell


)排序——缩小增量



五、归并排序



六、快速排序



七、堆排序



八、拓扑排序



九、锦标赛排序



十、基数排序






一、冒泡(


Bubble


)排序




----------------------------------Code


从小到大排序


n


个数

< br>------------------------------------


void BubbleSortArray()


{


for(int i=1;i


{


for(int j=0;i


{ < /p>


if(a[j]>a[j+1])//


比较交换相邻元素



{


int temp;


temp=a[j]; a[j]=a[j+1]; a[j+1]=temp;


}


}


}


}


------------------------- ------------------------Code---------------------- --------------------------


效率


O



n


?)


,


适用于排序小列表。

< p>




二、选择排序



----------------------------------Code


从小到大排序


n


个数

< br>--------------------------------


void SelectSortArray()


{


int min_index;


for(int i=0;i


{


min_index=i;


for(int j=i+1;j


每次扫描选择最小项



if(arr[j]


if(min_index!=i)//


找到最小项交换,即将 这一项移到列表中的正确位置



{


int temp;


temp=arr[i]; arr[i]=arr[min_index]; arr[min_index]=temp;


}


}


}

< br>----------------------------------------------- --Code----------------------------------------- < /p>


效率


O



n


?),适用于排序小的列表。





三、插入排序


< br>--------------------------------------------Cod e


从小到大排序


n


个数


-------------------------------------


void InsertSortArray()


{


for(int i=1;i


循环从第二个 数组元素开始,因为


arr[0]


作为最初已排序部分



{


int temp=arr[i]; //temp


标记为未排序第一个元素



int j=i-1;


while (j>=0 && a rr[j]>temp)/*



temp


与已排序元素从小到大比较,寻找


temp


应插入的位置


*/


{


arr[j+1]=arr[j];


j--;


}


arr[j+1]=temp;


}


}


----------- -------------------Code--------------------------- -----------------------------------


最佳 效率


O



n


) ;最糟效率


O



n

?)与冒泡、选择相同,适用于排序小列表



若列表基本有序,则插入排序比冒泡、选择更有效率。





四、壳(


Shell


)排序——缩小增量排序



-------------------------------------Code


从小到大排序


n


个数


---- ---------------------------------


void ShellSortArray()


{


for(int incr=3;incr<0;incr--)//


增量递减,以增量

< br>3



2



1


为例



{


for(int L=0;L<(n-1)/incr;L++)//

< br>重复分成的每个子列表



{


for(int i=L+incr;i

< br>对每个子列表应用插入排序



{


int temp=arr[i];


int j=i-incr;


while(j>=0&&arr[j]>temp)


{


arr[j+incr]=arr[j];


j-=incr;


}


arr[j+incr]=temp;


}


}


}


}

< br>--------------------------------------Code----- --------------------------------------


适用于排序小列表。



效率估计


O



nlog2^n



~O



n^1.5


),取决于增量值的最初大小。建议使用质数作为增量值,因为如果增量值是


2


的幂,则在下一个通道中会再次比较相同的


元素。



壳(


Shell


)排序 改进了插入排序,减少了比较的次数。是不稳定的排序,因为排序过程中元素可能会前后跳跃。

< br>




五、归并排序



--------- -------------------------------------Code

< br>从小到大排序


------------------------------ ---------


void MergeSort(int low,int high)


{


if(low>=high) return;//


每个子列表中剩下一个元素时停止



else int mid=(low+high)/2;/*


将列表划分成相等的两个子列表


,


若有奇数个元素,则在左边子 列表大于右侧子列表


*/


MergeSort(low,m id);//


子列表进一步划分



MergeSort(mid+1,high);


int [] B=new int [high- low+1];//


新建一个数组,用于存放归并的元素



for(int i=low,j=mid+1,k=low;i<=mid && j <=high;k++)/*


两个子列表进行排序归并,直到两个子列表中的一个结束< /p>


*/


{


if (arr[i]<=arr[j];)


{


B[k]=arr[i];


I++;


}


else


{ B[k]=arr[j]; j++; }


}


for( ;j<=high;j++,k++)//


如果第二个子列表中仍然有元素,则追加到新 列表



B[k]=arr[j];


for( i<=mid;i++,k++)//


如果在第一 个子列表中仍然有元素,则追加到新列表中



B[k]=arr[i];


for(int z=0;z


将排序的数组


B




所有元素复制到原始数组


arr




arr[z]=B[z];


}


-------------------------------------------------- ---Code------------------------------------------- --------


效率


O



nlogn


),归并的最佳、平均和最糟用例效率之间没有差异。



适用于排序大列表,基于分治法。




六、快速排序


< br>------------------------------------Code------- -------------------------------------


/*


快速排序的算法思想:选定一个枢纽元素,对待排序序列进行分割,分割之后的序列 一个部分小于枢纽元素,一个部分大于枢纽元素,再对这两个分割好的


子序列进行上述的 过程。


*/ void swap(int a,int b){int t;t =a ;a =b b =t }


int Partition(int [] arr,int low,int high)


{


int pivot=arr[low];//


采用子序列的第 一个元素作为枢纽元素



while (low < high)


{


//


从后往前栽 后半部分中寻找第一个小于枢纽元素的元素



while (low < high && arr[high] >= pivot)


{


--high;


}


//


将这个比枢纽元素小的元素交换到前半部分



swap(arr[low], arr[high]);


//


从前往后在前半部分中寻找第一个大于枢纽元素的元素



while (low


{


++low


}


swap (arr [low ],arr [high ]);//


将这个枢纽元素大的元素交换到后半部分



}


return low ;//


返回枢纽元素所在的位置



}


void QuickSort(int [] a,int low,int high)


{


if (low


{


int n=Partition (a ,low ,high );


QuickSort (a ,low ,n );


QuickSort (a ,n +1,high );


}


}


----------- -----------------------------Code----------------- --------------------


平均效率


O< /p>



nlogn


),适用于排序大列表。< /p>



此算法的总时间取决于枢纽值的位置;选择第一个元素作为枢 纽,可能导致


O



n

< br>?)的最糟用例效率。若数基本有序,效率反而最差。选项中间值作为枢纽,


效率 是


O



nlogn

)。



基于分治法。






七、堆排序



最大堆:后者任一非终 端节点的关键字均大于或等于它的左、右孩子的关键字,此时位于堆顶的节点的关键字是整个序列中最大的。



思想:



( 1)



i=l,


并令

< br>temp



kl


(2 )


计算


i


的左孩子

j=2i+1;


(3)



j<



n



1


,则转


(4),


否则转

(6);


(4)


比较


kj



kj+1,



k j+1>kj,


则令


j



j



1


,否则


j


不变;



(5)


比较


temp



kj


,若


kj>temp


,则令

< p>
ki


等于


kj


,并令


i=j,j=2i+1,


并转


(3),


否则转


(6)


(6)

< br>令


ki


等于


temp

< p>
,结束。



---------------- -------------------------Code--------------------- ------


void HeapSort(SeqIAst R)



{ //



R[1..n]


进行堆排序,不妨用


R[0]

< br>做暂存单元


int I; BuildHeap(R)



//



R[1-n]


建成初始堆


for(i= n;i>1



i--) //


对当前无 序区


R[1..i]


进行堆排


序,共做


n-1


趟。


{ R[0]=R[1]; R[1]=R[i]; R[i]=R[0]; //


将堆顶和堆中最后一个记录交换


Heapify(R,1,i-1); //



R[1..i- 1]


重新调整为堆,仅有


R[1]


可< /p>


能违反堆性质


} } ------------------ ---------------------Code------------------------- -------------




堆排序的时间,主要由建立初始堆和反复重建堆这两部分的时间开销构成,它们均是通过调用

Heapify


实现的。



< /p>


堆排序的最坏时间复杂度为


O(nlgn)



堆排序的平均性能较接近于最坏性能。


< br>由于建初始堆所需的比较次数较多,


所以堆排序不适宜于记录数较少的文件。




排序是就地排序,辅助空间为


O(1)




它是不稳定的排序方法。





堆排序与直接插入排序的区别


:


直接选择排序中,为了从


R[1..n]


中选出关键字最小的记录,必须进行


n-1


次比较,然后在< /p>


R[2..n]


中选出关键字最小的记录,又需要做


n-2


次比较。事实上,


后面的

n-2


次比较中,有许多比较可能在前面的


n-1


次比较中已经做过,但由于前一趟排序时未保留这些比较结果,所以后一趟排序时又重复执行了这 些比较


操作。



堆排序可通过树形结构保存部分比较结果,可减少比较次数。





八、拓扑排序





:学生选修课排课先后顺序



拓扑排 序:把有向图中各顶点按照它们相互之间的优先关系排列成一个线性序列的过程。



方法:



在有向图中选一个没有前驱的顶点且输出



从图中删除该顶点和所有以它为尾的弧


重复上述两步,直至全部顶点均已输出(拓扑排序成功),或者当图中不存在无前驱的顶点(图中有回路)为 止。



------------------------ ---------------Code------------------------------- -------


void TopologicalSort()/*


输出拓扑排序函数。若


G


无回路,则输出

< p>
G


的顶点的一个拓扑序列并返回


OK


,否则返回


ERROR*/


{


int indegree[M];


int i,k,j;


char n;


int count=0;


Stack thestack;


FindInDegre e(G,indegree);//


对各顶点求入度


indeg ree[0....num]


InitStack(thestack);//


初始化栈



for(i=0;i<;i++)


ine(


结点



的入度为



for(i=0;i<;i++)


{


if(indegree[i]==0)


Push(es[i]);


}


(


拓扑排序输出顺序为:



while( ()!=null)


{


Pop(());


j=locatevex(G,n);


if (j==-2)


{


ine(


发 生错误,程序结束。



exit();


}


(es[j].data);


count++;


for(p=es[j].firstarc;p!=NULL;p=c)


{


k=;


if (!(--indegree[k]))


Push(es[k]);


}


}


if (count<)


ine(


该图有环,出现错误,无法排序。


else


ine(


排序成功。< /p>



}


--------------- -------------------------Code--------------------- -----------------


算法的时间复杂度


O



n+e


)。






九、锦标赛排序



锦标赛排序的算法思想与体育比赛类似。


< br>首先将


n


个数据元素两两分组,分别按关键字进行比较, 得到


n



2


个 比较的优胜者


(


关键字小者


)


,作为第一步比较的结果保留下来,



然后对 这


n



2


个数 据元素再两两分组,分别按关键字进行比较,?,如此重复,直到选出一个关键字最小的数据元素为止。






--------------------------------Code in C---------------------------------------


#include


#include


#include


#include


#define SIZE 100000


#define MAX 1000000


struct node


{


long num;//


关键字



char str[10];


int lastwin;//


最后胜的对手



int killer;//


被击败的对手



long times;//


比赛次数



}data[SIZE];


long CompareNum=0;


long ExchangeNum=0;


long Read(char name[])//


读取文件



中的数据,并存放在数组


data[]


中;最后返回数据的个数



{


FILE *fp;


long i=1;


fp=fopen(name,


fscanf(fp,


while(!feof(fp))


{


i++;


fscanf(fp,


}


return (i-1);


}


long Create(long num)//


创建胜者树 ,返回冠军(最小数)在数组


data[]


中的下标

< p>


{


int i,j1,j2,max,time=1;


long min;//


记录当前冠军的下标



for(i=1;pow(2,i-1)


;


max=pow(2,i-1);//

< br>求叶子结点数目



for(i=1;i<=max;i ++)//


初始化叶子结点



{


data[i].killer=0;


data[i].lastwin=0;


data[i].times=0;


if(i>num)


data[i].num=MAX;


}


for(i=1;i<=max;i+=2)//


第一轮比赛

< br>


{


++CompareNum;


if(data[i].num <= data[i+1].num)


{


data[i].lastwin = i+1;


data[i+1].killer=i;


++data[i].times;


++data[i+1].times;


min=i;


}


else


{


data[i+1].lastwin=i;


data[i].killer=i+1;


++data[i].times;


++data[i+1].times;


min=i+1;


}


}


j1=j2=0;//< /p>


记录连续的两个未被淘汰的选手的下标



while(time <= (log(max)/log(2)))//


进行淘汰赛



{


for(i=1;i<=max;i++)


{


if(data[i].times==time && data[i].killer==0)//


找到一名选手



{


j2=i;//


默认其为两选手 中的后来的



if(j1==0)//


如果第一位置是空的,则刚来的选手先来的



j1=j2;


else//


否则刚来的选手是后来的,那么选手都已到场比赛 开始



{


++CompareNum;


if(data[j1].num <= data[j2].num)//


先来的选手获胜



{


data[j1].lastwin = j2;//


最后赢的是


j2


dat a[j2].killer=j1;//j2


是被


j1


淘汰的



++data[j1].times;


++data[j2 ].times;//


两选手场次均加


1


min=j1;//


最小数下标为


j1


j1=j2=0;//



j1



j2



0


}


else//


同理



{


data[j2].lastwin=j1;


data[j1].killer=j2;


++data[j1].times;


++data[j2].times;


min=j2;


j1=j2=0;


}


}


}



}


time++;//


轮数加


1


}


return min;//


返回冠军的下标



}


void TournamentSort(long num)//


锦标赛排序



{


long tag=Create(num);//


返回最小数下标



FILE *fp1;


fp1=fopen(


为写入创建并打开文件



while(data[tag].num != MAX)//


当最小值不是无穷大时



{


printf(


输出数据



fprintf(fp1,


写入数据



data[tag].num=MAX;//


将当前冠军用无穷 大替换



tag=Create(num);//

< p>
返回下一个冠军的下标



}


}


int main()


{


int num;


char name[10];


printf(


gets(name);

< br>num=Read(name);//


读文件



TournamentSort(num);//


锦标赛排序



printf(


return 0;


}

-


-


-


-


-


-


-


-



本文更新与2021-02-01 21:24,由作者提供,不代表本网站立场,转载请注明出处:https://www.bjmy2z.cn/gaokao/595178.html

SMART算法总结的相关文章

  • 爱心与尊严的高中作文题库

    1.关于爱心和尊严的作文八百字 我们不必怀疑富翁的捐助,毕竟普施爱心,善莫大焉,它是一 种美;我们也不必指责苛求受捐者的冷漠的拒绝,因为人总是有尊 严的,这也是一种美。

    小学作文
  • 爱心与尊严高中作文题库

    1.关于爱心和尊严的作文八百字 我们不必怀疑富翁的捐助,毕竟普施爱心,善莫大焉,它是一 种美;我们也不必指责苛求受捐者的冷漠的拒绝,因为人总是有尊 严的,这也是一种美。

    小学作文
  • 爱心与尊重的作文题库

    1.作文关爱与尊重议论文 如果说没有爱就没有教育的话,那么离开了尊重同样也谈不上教育。 因为每一位孩子都渴望得到他人的尊重,尤其是教师的尊重。可是在现实生活中,不时会有

    小学作文
  • 爱心责任100字作文题库

    1.有关爱心,坚持,责任的作文题库各三个 一则150字左右 (要事例) “胜不骄,败不馁”这句话我常听外婆说起。 这句名言的意思是说胜利了抄不骄傲,失败了不气馁。我真正体会到它

    小学作文
  • 爱心责任心的作文题库

    1.有关爱心,坚持,责任的作文题库各三个 一则150字左右 (要事例) “胜不骄,败不馁”这句话我常听外婆说起。 这句名言的意思是说胜利了抄不骄傲,失败了不气馁。我真正体会到它

    小学作文
  • 爱心责任作文题库

    1.有关爱心,坚持,责任的作文题库各三个 一则150字左右 (要事例) “胜不骄,败不馁”这句话我常听外婆说起。 这句名言的意思是说胜利了抄不骄傲,失败了不气馁。我真正体会到它

    小学作文