堆排序和桶排序
升序排列 维持大顶堆状态 每次交换最后一个元素并输出
桶排序 找出待排序列大小值区间,分桶,将待排序列分入桶中分别排列,按桶号合并。
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);
}
}
}