寒冬.排序

这篇博客介绍了三种不同的排序算法:堆排序、桶排序和竞赛树(胜者树)。堆排序通过构建大顶堆进行升序排列,桶排序则是根据数值范围分桶,然后对每个桶内的元素排序后再合并。竞赛树(败者树)则用于外部大文件的排序,通过不断合并小块数据并更新最小值,直至完成排序。此外,还提到了混合排序,结合归并排序和败者树进行多路归并,有效处理大型数据文件的排序问题。
摘要由CSDN通过智能技术生成

堆排序和桶排序

升序排列 维持大顶堆状态 每次交换最后一个元素并输出

桶排序 找出待排序列大小值区间,分桶,将待排序列分入桶中分别排列,按桶号合并。

public class HeapSort {
public static int arr[]=new int[1000];
public static void swap(int i,int j)
{
	int temp=arr[i];
	arr[i]=arr[j];
	arr[j]=temp;
}
public static void Heapsort()
{
	int index;
	for(index=arr.length/2;index>=0;index--)
	{
		Adjust(index,arr.length-1);
	}
	for(index=arr.length-1;index>=1;index--)
	{
		swap(0,index);//every round swap the root and the bigger
		Adjust(0,index-1);//adjust
	}
}
// adjust to the big heap
public static void Adjust(int s,int m)
{
	int temp,j;
	temp=arr[s];
	for(j=2*s;j<=m;j*=2)
	{
		if(j<m&&arr[j]<arr[j+1])
		{
			j++;
		}
		if(temp>=arr[j])
		{
			break;
		}
		arr[s]=arr[j];
		s=j;
	}
	arr[s]=temp;
}
public static void Bucketsort()
{
	int min=65535;
	int max=0;
	int minsign=0;
	int maxsign=0;
	for(int i=0;i<arr.length;i++)
	{
		if(arr[i]<min)
		{
			min=arr[i];
			minsign=i;
		}
		if(arr[i]>max)
		{
			max=arr[i];
			maxsign=i;
		}
	}
	int a=max/5;
	ArrayList bucket[]=new ArrayList[5];
	for(int i=0;i<bucket.length;i++)
	{
		bucket[i]=new ArrayList<Integer>();
	}
	for(int i=0;i<arr.length;i++)
	{
		if(arr[i]<a)
		{
			bucket[0].add(arr[i]);
		}
		if(arr[i]>=a&&arr[i]<2*a)
		{
			bucket[1].add(arr[i]);
		}
		if(arr[i]>=2*a&&arr[i]<3*a)
		{
			bucket[2].add(arr[i]);
		}
		if(arr[i]>=3*a&&arr[i]<4*a)
		{
			bucket[3].add(arr[i]);
		}
		if(arr[i]>=4*a&&arr[i]<=max)
		{
			bucket[4].add(arr[i]);
		}
	}
	for(int i=0;i<bucket.length;i++)
	{
		bucket[i].sort(null);
	    for(int j=0;j<bucket[i].size();j++)
	    {
	    	System.out.print(bucket[i].get(j)+" ");
	    }
	}	
}
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int i1=0;
		String fileName="D:\\datafile.txt";
		try {
			Scanner sc=new Scanner(new FileReader(fileName));
			sc.useDelimiter(",");
			while(sc.hasNextInt())
			{
				int intvalue=sc.nextInt();
				arr[i1]=intvalue;
				i1++;
				if(i1>=1000) break;
			}
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
        //Heapsort();
        for(int i=0;i<arr.length;i++)
        {
        	System.out.print(arr[i]+" ");
        }
        //Bucketsort();
	}

}

胜者树

将待排序列进行合并操作,并让大的值成为根节点,每次输出根节点的同时到相应叶子节点将其赋为最小值,重复上述过程直到根成为默认最小值结束。

public class TreeNode {
TreeNode lchild;
TreeNode rchild;
TreeNode parent;
int data;
int[] value;
TreeNode(int i)
{
	value=new int[i];
	lchild=null;
	rchild=null;
	parent=null;
}
TreeNode()
{
	lchild=null;
	rchild=null;
	parent=null;
}
}
public class WinnerTree {
	public static int UNIT=65535;
public static int arr[]= {3,2,1};
public static TreeNode root;
public static Queue que=new LinkedList();
public static void createTree()
{
	for(int i=0;i<arr.length;i++)
	{
		TreeNode p=new TreeNode();
		p.data=arr[i];
		que.offer(p);
	}
	for(int i=arr.length;i<2*arr.length-1;i++)
	{
		TreeNode p1= (TreeNode) que.poll();
		TreeNode p2= (TreeNode) que.poll();
		TreeNode p=new TreeNode();
		p1.parent=p;
		p2.parent=p;
		p.lchild=p1;
		p.rchild=p2;
		p.data=p1.data<p2.data?p1.data:p2.data;
		root=p;
		que.offer(p);
	}
}
public static void find()
{
	TreeNode p=root;
	while(root.data!=UNIT)
	{
		System.out.println(root.data);
	while(p.lchild!=null&&p.rchild!=null)
	{
		if(p.lchild.data==root.data)
		{
			p=p.lchild;
		}
		else if(p.rchild.data==root.data)
		{
			p=p.rchild;
		}
	}
	p.data=UNIT;
		while(p.parent!=null)
		{
			p.parent.data=(p.parent.lchild.data<p.parent.rchild.data)?p.parent.lchild.data:p.parent.rchild.data;
			p=p.parent;
		}
	}
}
	public static void main(String[] args) {
		// TODO Auto-generated method stub
        createTree();
        find();
	}

}

竞赛树与归并排序(k路归并)

利用归并排序对外存文件中的数据进行划分,使其成为小归并块,每个小块进行归并的内排序,最后通过竞赛树(由于划分为数组,这里采用败者树的方式进行归并),需要一个败者树数组los,一个标记当前各个序列最小值索引的kfirst。归并输出到文件,实现外部大文件的排序,弥补了归并排序的不足。详解看代码 

public class MixSort {
	public static String fileName="D:\\datafile.txt";
	public static String filename="D:\\datafile1.txt";
	public static int  MINKEY= -1;  //假设所有数据都大于与该值
	public static int  MAXKEY=65535; //假设所有数据都小与该值
	public static int[] arr=new int[100];
	public static int[] arr0=new int[20];
	public static int[] arr1=new int[20];
	public static int[] arr2=new int[20];
	public static int[] arr3=new int[20];
	public static int[] arr4=new int[20];
	public static void merge(int begin,int mid,int end,int[] temp,int[] a)
	{
		int i=begin;
		int j=mid+1;
		int k=0;
		int m=mid;int n=end;
		while(i<=m&&j<=n)
		{
			if(a[i]<a[j])
			{
				temp[k++]=a[i++];
			}
			else
			{
				temp[k++]=a[j++];
			}
		}
		while(i<=m)
		{
			temp[k++]=a[i++];
		}
		while(j<=n)
		{
			temp[k++]=a[j++];
		}
		for(int index=0;index<k;index++)
		{
			a[index+begin]=temp[index];
		}
	}
	public static void mergesort(int[] temp,int begin,int end,int[] a)
	{
		if(begin<end)
		{
			int mid=(begin+end)/2;
			mergesort(temp,begin,mid,a);
			mergesort(temp,mid+1,end,a);
			merge(begin,mid,end,temp,a);
		}
	}
	public static void  main(String[] args)
	{
		System.out.println("sign");
		int i1=0;
		int count=0;
		int count1=0;
		int count2=0;
		int count3=0;
		int count4=0;
		try {
			Scanner sc=new Scanner(new FileReader(fileName));
			sc.useDelimiter(",");
			while(sc.hasNextInt())
			{
				if(i1>=arr.length) break;
				int intvalue=sc.nextInt();
				if(i1<arr0.length)
				{
					arr0[count++]=intvalue;
					i1++;
				}
				if(i1<2*arr1.length&&i1>=arr0.length)
				{
					arr1[count1++]=intvalue;
					i1++;
				}
				if(i1<3*arr0.length&&i1>=2*arr1.length)
				{
					arr2[count2++]=intvalue;
					i1++;
				}
				if(i1<4*arr0.length&&i1>=arr0.length*3)
				{
					arr3[count3++]=intvalue;
					i1++;
				}
				if(i1<arr.length&&i1>=arr0.length*4)
				{
					arr4[count4++]=intvalue;
					i1++;
				}
			}
		int[] a0=arr0.clone();
		int[] a1=arr1.clone();
		int[] a2=arr2.clone();
		int[] a3=arr3.clone();
		int[] a4=arr4.clone();
			mergesort(a0,0,arr0.length-1,arr0);
			mergesort(a1,0,arr1.length-1,arr1);
			mergesort(a2,0,arr2.length-1,arr2);
			mergesort(a3,0,arr3.length-1,arr3);
			mergesort(a4,0,arr4.length-1,arr4);
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	    int[][] arr11={arr0,arr1,arr2,arr3,arr4};
	    //总共K路
	    int k = arr11.length;
	    int[] arrayCount=new int[k];
	    arrayCount[0] =arr0.length; 
	    arrayCount[1] =arr1.length;
	    arrayCount[2] =arr2.length;
	    arrayCount[3] =arr3.length; 
	    arrayCount[4] = arr4.length;
	    //用于构建供几个序列的当前最小元素比较的败者树
	    int[] los=new int[k];
	    //存放每一路的首元素 后续存放该序列未参与比赛的最小元素
	    int[] kfirst=new int[k+1];
	    //创建败者树
	    createLoserTree(arr11,kfirst,los,k);
	    //进行多路归并
	    kMerge(arr11, arrayCount, k, los,kfirst);
}
	public static void createLoserTree(int[][] arry, int[] kfirst,int[] los,int k)
	{
	    for (int i = 0; i < k; ++i){
	        kfirst[i] = arry[i][0];//每一路首元素进行赋值
	    }
	    //最后一个元素用于存放默认的最小值
	    kfirst[k] = MINKEY;
	    for (int i=0; i < k; i++) {
	        los[i] = k;
	    }
	    //由底到根调整
	    for (int i = k - 1; i >= 0; --i){
	        adjust(kfirst, los, i, k);
	    }
	}
/**
	 * 调整败者树,得出最终胜者
	 */
	public static void adjust(int[] kfirst,int[] los,int s,int k)
	{
	    //t为b[s]在败者树中的父结点
	    int t = (s + k) / 2;
	    while (t > 0) {//0是根
	        if (kfirst[s] > kfirst[los[t]]){
	            //los[t]记录败者所在的索引,s为新的胜者,胜者继续在败者树中进行比较
	            int temp=s;
	    		s=los[t];
	    		los[t]=temp;
	        }
	        t/= 2;//获取下一个父节点
	    }
	    //最终的胜者也就是最小的叶节点记录于los[0]
	    los[0] = s;
	}
	public static void kMerge(int[][] arr11, int[] arrayCount, int k, int[] los, int[] kfirst)
	{
		 FileWriter fw = null;
	    int[] index=new int[k];
	    for (int i = 0; i < k; i++){
	        index[i] = 0;
	    }
		try {
			fw = new FileWriter(filename);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	    while (kfirst[los[0]]!=MAXKEY) {
	        int s = los[0];  
	        System.out.print(kfirst[s]+" "); 
			try {
				fw.write(kfirst[s]+",");
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
	        index[s]++;
	        if (index[s] < arrayCount[s]){
	             kfirst[s] = arr11[s][index[s]];//该序列的下一位进入败者树进行比较
	        }else{
	            kfirst[s] = MAXKEY;
	        }
	        adjust(kfirst, los, s, k);
	    }
	}
}

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值