计算机软件技术编程基础 排序.ppt
(40页)
本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦!
19.90 积分
基本排序技术排序是将一个无序序列整理成非递减顺序排列的有序序列。稳定排序:排序过程中,相同关键字的元素的相对次序不变。不稳定排序:排序过程中,相同关键字的元素的相对次序发生变化。例如:34,12,34`,08,96 08,12,34, 34`,96 稳定 08,12, 34`,34,96 不稳定一 交换排序比较两个待排序纪录的关键字,若为逆序则相互交换位置,否则,保持原来位置不变。冒泡排序、快速排序1 冒泡排序基本思想:从前往后扫描,逐个比较相邻的两个元素,发现倒序即交换——直到将第N-1个纪录和第N个记录交换为止。51731694286原序列517316942861 53 71 76 74 92 98 96 9关键字最大的安置到最后从后往前扫描,将第N-1个纪录和前一个关键字进行比较,将小的放在前面,大的放在后面,依次类推,直到第2个记录和第1个记录交换为止。153167428696 82 42 71 31 52 6关键字最小的安置到最前面15316742869115326746893 52 54 76 7113256467894 64 52 3对剩余的线性表重复操作对线性表的每次来回操作都将最大的沉到表底,最小的像气泡冒到表头。1153267468911325646789112345667891531674286951731694286115326746891132564678911234566789012345678910void bub(int p[],int n){ int m,k,j,i; int d; k=0;m=n-1; //初始时子表表头k和表尾m位置 while(k=j;i--) if(p[i-1]>p[i]) {d=p[i];p[i]=p[i-1];p[i-1]=d;k=i;} } return;}待排数组数组长度while(k扫描无交换,表尾置0 for(i=k;i扫描,子表p[m+1]沉底 if(p[i]>p[i+1]) {d=p[i];p[i]=p[i+1];p[i+1]=d;m=i;}//m为该趟冒泡后子表表尾的位置 j=k+1;k=0; //如果=j;i--) //从p[i]) {d=p[i];p[i]=p[i-1];p[i-1]=d;k=i;}//k为该趟冒泡后子表表头的位置 }算法分析:稳定时间代价:需要进行比较的次数为2 快速排序1) 从无序表中选取一个元素T,对线性表进行分割,大于T的元素放在前表中,小于T的元素放在后表中。此时,线性表分成前后两个子表;2 )对分割的两个子表再进一步分割,直到所有的子表为空为止;无序线性表≤T≥TT分割分割分割i为表头位置; k 为表中位置; j为表尾位置比较大小,取中间值为分割元素t,该元素在表中的位置存放表头元素,将表头位置腾空;表尾位置前移(j--);该元素放入表头,表头位置后移(i++);P[j]>t从前往后扫描,p[i]P[i]<=t表头位置后移(i++);该元素放入表尾,表尾位置前移(j--) ;读入表尾元素;在一趟快速排序中,整个过程交替地从后往前扫描关键字值小的记录和从前往后扫描关键字值大的记录并放置到对应端空出的位置中,又空出新的位置。当从两个方向的扫描重合时,即i=j,就找到了基准记录的存放位置。 按照快速排序的基本思想,在一趟快速排序之后,需要重复(1),(2),直到找到所有记录的相应位置。快速排序是一个递归的过程。 快速排序算法是不稳定排序,对于有相同关键字的记录,排序后有可能颠倒位置。51731694286012345678910i=0;j=10;k=5;1731694286217316948621316978621431t=59786i=2t=52746插入排序 插入排序的基本思想是:每次将一个待排序的记录,按其关键字大小插入到前面已经排好序的子表中的适当位置,直到全部记录插入完成为止。也就是说,将待序列表分成左右两部分,左边为有序表(有序序列),右边为无序表(无序序列)。整个排序过程就是将右边无序表中的记录逐个插入到左边的有序表中,构成新的有序序列。根据不同的插入方法,插入排序算法主要包括:直接插入排序、折半插入排序、表插入排序和希尔排序等。本章重点介绍简单插入排序、希尔排序。 简单插入法:将一个记录插入到已排好序的有序表中基本思想:将待排序表看成左右两部分,左边为有序区,右边为无序区;整个排序过程就是将右边无序区的元素插入到左边有序区中。(插入时,有序子表从最后一个元素开始,逐个向前与待插入元素比较)数据表a={12,5,4,9,5}从小到大排序12549512495512551295412544512591294591251295void insort(T p[],int n){ int j,k; T t; for(j=1;j=0)&&(p[k]>t)) //如果有序子表的元素大于待排序元素 { p[k+1]=p[k];//有序子表的元素后移 k=k-1;//向前寻找有序子表的下一个比较元素 } p[k+1]=t;//待排序元素插入到有序子表 } return;}【例】假设有7个待排序的记录,它们的关键字分别为23,4,15,8,19,24,15,用直接插入法进行排序。【解】简单插入排序过程如图所示。方括号[ ]中为已排好序的记录的关键字,有两个记录的关键字都为15,为表示区别,将后一个15加下划线。 简单插入排序 for (j=1;jdata data >=b的父结点的值,*s插入到b的右子树中80828575826871778875828085826871778856783445854536918478构造二叉排序树34845685783645459178如何定义结点?struct bsnode{ int d; bsnode *lchild,*rchild;};bsnode *insert_bs_tree(bsnode *bt, int x)二叉排序树的插入 insert_bs_tree( )传入的形参:根结点,插入元素insert_bs_tree(bsnode *bt, int x)返回值:根结点bsnode *insert_bs_tree(bsnode *bt, int x){bsnode *p,*q;定义两个结点构造一个新结点p=new(bsnode); p->d=x;p->lchild=NULL;p->rchild=NULL;建立一个搜索指针,从根结点开始搜索q=bt;如果二叉排序树为空,将新结点作为根结点if(bt==NULL) bt=p;如果二叉排序树不为空,将新结点插入到二叉树中else {while((q->lchild!=p)&&(q->rchild!=p)) {判断新结点是否插入到二叉树中if(xd) { if(q->lchild!=NULL) q=q->lchild; else q->lchild=p; }如果插入值小于搜索结点q的值1搜索结点q的左子树的结点已存在2搜索结点q的左子树为空如果插入值大于搜索结点q的值1搜索结点q的右子树的结点已存在2搜索结点q的右子树为空else { if(q->rchild!=NULL) q=q->rchild; else q->rchild=p; } } } return bt;}返回根结点二叉排序树的查找从二叉排序树的根结点开始与被查值进行比较,若等于根结点,则查找结束根结点,到右子树查找;void intrav(bsnode *bt){ if(bt!=NULL) { intrav(bt->lchild); cout
天天文库所有资源均是用户自行上传分享,仅供网友学习交流,未经上传用户书面授权,请勿作他用。