快速排序

     今天上午开始看的快速排序,原理百度出来的:

     

设要排序的 数组是A[0]……A[N-1],首先任意选取一个数据(通常选用数组的第一个数)作为关键数据,然后将所有比它小的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一趟快速排序。值得注意的是,快速排序不是一种稳定的 排序算法,也就是说,多个相同的值的相对位置也许会在算法结束时产生变动。
一趟快速排序的算法是:

1)设置两个变量i、j, 排序开始的时候:i=0,j=N-1;
2)以第一个数组元素作为关键数据,赋值给 key,即 key=A[0];
3)从j开始向前搜索,即由后开始向前搜索(j--),找到第一个小于 key的值A[j],将A[j]和A[i]互换;
4)从i开始向后搜索,即由前开始向后搜索(i++),找到第一个大于 key的A[i],将A[i]和A[j]互换;
5)重复第3、4步,直到i=j; (3,4步中,没找到符合条件的值,即3中A[j]不小于 key,4中A[i]不大于 key的时候改变j、i的值,使得j=j-1,i=i+1,直至找到为止。找到符合条件的值,进行交换的时候i, j指针位置不变。另外,i==j这一过程一定正好是i+或j-完成的时候,此时令循环结束)。
然后自己写的第一遍排序的代码:
<pre name="code" class="java">package testjson;

import org.junit.Test;

public class Quicksort {
	private int i;
	private int j;
	int t = 0;
	int[] tie = new int[5];

	public int qp(int[] score, int i, int j) {
		int temp;
		int key;
		int n = j;
		int m = i;

		key = score[i];
		for (j = n; j > i; j--) {
			if (score[j] < key) {
				temp = score[j];
				score[j] = score[i];
				score[i] = temp;
				for (i = m; i < j; i++) {
					if (score[i] > key) {
						temp = score[i];
						score[i] = score[j];
						score[j] = temp;
						break;
					}
				}

			}

		}
		System.out.println("排序完成后的结果:");
		for (i = 0; i < score.length; i++) {
			System.out.print(score[i] + ",");
		}
		return j;

	}

	@Test
	public void test() {
		int[] score = { 3, 5, 9, 2, 1, 8, 4, 6 };

		i = 0;
		j = score.length - 1;
		qp(score, i, j);
	}
}
 
全部排序完成需要用到递归算法,自己写的递归感觉很正确
package testjson;

import org.junit.Test;

public class Quicksort {
	private int i;
	private int j;
	int t = 0;
	int[] tie = new int[5];

	public int qp(int[] score, int i, int j) {
		int temp;
		int key;
		int n = j;
		int m = i;

		key = score[i];
		for (j = n; j > i; j--) {
			if (score[j] < key) {
				temp = score[j];
				score[j] = score[i];
				score[i] = temp;
				for (i = m; i < j; i++) {
					if (score[i] > key) {
						temp = score[i];
						score[i] = score[j];
						score[j] = temp;
						break;
					}
				}

			}

		}

		qp(score, j + 1, score.length - 1);

		qp(score, i, j - 1);

		System.out.println("排序完成后的结果:");
		for (i = 0; i < score.length; i++) {
			System.out.print(score[i] + ",");
		}
		return j;

	}

	@Test
	public void test() {
		int[] score = { 3, 5, 9, 2, 1, 8, 4, 6 };

		i = 0;
		j = score.length - 1;
		qp(score, i, j);

	}
}
调试了几次逻辑走的不对,ij在第二次快排的时候最后值都不同,最后看了别人的分析才知道用到不只是递归,递归只是解决问题的方式,用的分治法,分治法的大致思想是,把问题分为小问题,用递归或者其他方式解决小问题,再把小问题合起来为问题本身
以下是别人的分析:

它的一般的算法设计模式如下:

Divide-and-Conquer(P)

1. if |P|≤n0

2. then return(ADHOC(P))

3. 将P分解为较小的子问题 P1 ,P2 ,…,Pk

4. for i←1 to k

5. do yi ← Divide-and-Conquer(Pi) △ 递归解决Pi

6. T ← MERGE(y1,y2,…,yk) △ 合并子问题

7. return(T)

其中|P|表示问题P的规模;n0为一阈值,表示当问题P的规模不超过n0时,问题已容易直接解出,不必再继续分解。ADHOC(P)是该分治法中的基本子算法,用于直接解小规模的问题P。因此,当P的规模不超过n0时直接用算法ADHOC(P)求解。算法MERGE(y1,y2,…,yk)是该分治法中的合并子算法,用于将P的子问题P1 ,P2 ,…,Pk的相应的解y1,y2,…,yk合并为P的解。

所以我的问题出在,我并没有把问题明显的细分,我只用到递归,而且递归用的不对,关键的代码是:

int middle = getMiddle(list, low, high);  //将list数组进行一分为二     
 
               _quickSort(list, low, middle - 1);        //对低字表进行递归排序     
 
              _quickSort(list, middle + 1, high);       //对高字表进行递归排序   

这么看我的问题出在我没有划分明确,逻辑思路有点混乱,还好自己已经测试完成明白了整体的流程,完全画了流程图
下边附带一下完整的代码,此代码为网上查找别人的代码改编,改日再自己写代码:
package testjson;

import org.junit.Test;

//网上找的实例
public class Zquicksort {
	
	 
		  
	    int a[] = {3,5,9,2,1,8,4,6};
		  @Test  
		public void quickSort(){  
		  
		    quick(a);  
		  
		    for(int i=0;i<a.length;i++)  
		  
		       System.out.print(a[i]+",");  
		  
		}  
		  
		public int getMiddle(int[] list, int low, int high) {     
		  
		            int tmp = list[low];    //数组的第一个作为中轴     
		  
		            while (low < high) {     
		  
		                while (low < high && list[high] >= tmp) {     
		  
		                    high--;     
		  
		                }     
		  
		                list[low] = list[high];   //比中轴小的记录移到低端     
		  
		                while (low < high && list[low] <= tmp) {     
		  
		                    low++;     
		  
		                }     
		  
		                list[high] = list[low];   //比中轴大的记录移到高端     
		  
		            }     
		  
		           list[low] = tmp;              //中轴记录到尾     
		           //System.out.println(tmp+","+low);
		           System.out.println("排序完成后的结果:"+low);
		   		for(int p=0;p<a.length;p++){
		   		    System.out.print(a[p]+",");
		   		    }
		  
		            return low;                   //返回中轴的位置     
		  
		        }    
		  
		public void _quickSort(int[] list, int low, int high) {     
		  
		            if (low < high) {     
		  
		               int middle = getMiddle(list, low, high);  //将list数组进行一分为二     
		              
		                _quickSort(list, low, middle - 1);        //对低字表进行递归排序     
		           
		               _quickSort(list, middle + 1, high);       //对高字表进行递归排序     
		  
		            }     
		  
		        }   
		  
		public void quick(int[] a2) {     
		  
		            if (a2.length > 0) {    //查看数组是否为空     
		  
		                _quickSort(a2, 0, a2.length - 1);     
		  
		        }     
		  
		       }   
		  
		}  
		  


回头看自己写的代码,我用的是FOR循环,它写的是while循环,但是我的写法是错的,正确的写法改怎么写呢。自己没看出来。。回去问了问对象,解决了,是我最后没有break所以会再次j--然后再跳出循环,这个涉及到for循环本身的执行顺序:先执行j=7代入,然后第一遍循环完成之后执行j--,然后再次判断,如果成立继续执行,不成立则跳出。我再后边语句加了break就会直接跳出for循环,不至于进行再次判断。下边是别人说的百度的:
for(a;b;c)
执行顺序
先执行a
在判断b是否为真,若为真
执行循环体,
执行c
然后再次判断b是否为真,若为真
执行循环体
执行c
。。。
直到b为假,跳出循环
一下是改好的代码:
package testjson;

import org.junit.Test;

public class Quicksort {
	int[] score = { 3, 5, 9, 2, 1, 8, 4, 6 };

	public int qp(int[] score, int i, int j) {
		int temp;
		int key;
		int n = j;
		int m = i;

		key = score[i];
		for (j = n; j > i; j--) {
			if (score[j] < key) {
				temp = score[j];
				score[j] = score[i];
				score[i] = temp;
				for (i = m; i < j; i++) {
					if (score[i] > key) {
						temp = score[i];
						score[i] = score[j];
						score[j] = temp;
						break;
					}
				}

			}
			
			if(i==j){
				break;
			}

		}
		System.out.println("排序完成后的结果:"+j);
		for (i = 0; i < score.length; i++) {
			System.out.print(score[i] + ",");
		}
		return j;

	}

	public void quick(int[] list, int low, int high) {
		

		if (low < high) {     
			  
            int middle = qp(list, low, high);  //将list数组进行一分为二     
           
            quick(list, low, middle - 1);        //对低字表进行递归排序     
        
            quick(list, middle + 1, high);       //对高字表进行递归排序     

         }     
	}
	@Test
	public void test() {
		
		quick(score,0,score.length-1);
	}
}


快速排序到此技术,过两天过来改改语言表达。
本来不打算看非递归排序,感觉不怎么会用到,但是看了下别人写的代码用到栈了,这个得学啊,先留下网址,等以后看到栈的时候再看,先记录下
http://blog.csdn.net/yunzhongguwu005/article/details/9455991
http://www.douban.com/note/234724751/


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
城市应急指挥系统是智慧城市建设的重要组成部分,旨在提高城市对突发事件的预防和处置能力。系统背景源于自然灾害和事故灾难频发,如汶川地震和日本大地震等,这些事件造成了巨大的人员伤亡和财产损失。随着城市化进程的加快,应急信息化建设面临信息资源分散、管理标准不统一等问题,需要通过统筹管理和技术创新来解决。 系统的设计思路是通过先进的技术手段,如物联网、射频识别、卫星定位等,构建一个具有强大信息感知和通信能力的网络和平台。这将促进不同部门和层次之间的信息共享、交流和整合,提高城市资源的利用效率,满足城市对各种信息的获取和使用需求。在“十二五”期间,应急信息化工作将依托这些技术,实现动态监控、风险管理、预警以及统一指挥调度。 应急指挥系统的建设目标是实现快速有效的应对各种突发事件,保障人民生命财产安全,减少社会危害和经济损失。系统将包括预测预警、模拟演练、辅助决策、态势分析等功能,以及应急值守、预案管理、GIS应用等基本应用。此外,还包括支撑平台的建设,如接警中心、视频会议、统一通信等基础设施。 系统的实施将涉及到应急网络建设、应急指挥、视频监控、卫星通信等多个方面。通过高度集成的系统,建立统一的信息接收和处理平台,实现多渠道接入和融合指挥调度。此外,还包括应急指挥中心基础平台建设、固定和移动应急指挥通信系统建设,以及应急队伍建设,确保能够迅速响应并有效处置各类突发事件。 项目的意义在于,它不仅是提升灾害监测预报水平和预警能力的重要科技支撑,也是实现预防和减轻重大灾害和事故损失的关键。通过实施城市应急指挥系统,可以加强社会管理和公共服务,构建和谐社会,为打造平安城市提供坚实的基础。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值