数据结构4--查找和排序

来源:互联网 发布:景观大数据软件课程 编辑:程序博客网 时间:2024/05/17 07:08

一、查找

1.顺序查找

顺序查找是最基本的查找顺序,时间复杂度为O(n),查找过程为:从表中第一个元素开始按顺序逐个进行遍历,若查找到记录则返回,若直到最后一个没有查到,则查找失败。

2.二分查找

折半查找(Binary Search)技术,又称为二分查找,它的前提是线性表中的记录必须是关键码有序(通常从小到大有序),线性表必须采用顺序存储,其时间复杂度为O(logn)

基本思想在有序表中,取中间记录作为比较对象,若给定值与中间记录的关键字相等,则查找成功;若给定值小于中间记录的关键字,则在中间记录的左半区继续查找;若给定值大于中间记录的关键字,则在中间记录的右半区继续查找。不断重复上述过程,直到查找成功,或所有查找区域无记录,则查找失败。

3.查找树方法

(1)二叉查找树

二叉查找树又叫二叉排序树,需满足以下性质:

 1.若它的左子树非空,则左子树上所有记录的值均小于根记录的值;

 2.若它的右子树非空,则左子树上所有记录的值均小于根记录的值;

 3.左,右子树又各是一棵二叉查找树。

(2)平衡二叉树

定义:它的左子树和右子树的深度之差的绝对值不超过1,且它的左子树和右子树都是一颗平衡二叉树。

平衡因子(BF):结点的左子树的深度减去右子树的深度,那么显然-1<=bf<=1;

二、排序

1.插入类排序

基本思想:不断地将待排序的元素插入到有序序列中,使有序序列不断地扩大,直至所有元素都被插入到有序序列中。

(1)直接插入排序

基本操作:将一个记录插入到已经排好序的有序表中,从而得到一个新的,记录数增1的有序表。

注:最好情况时间复杂度为O(n),最坏为O(n2).

(2)希尔排序

基本思想:将待排序的记录分成几组,从而减少参与直接插入排序的数据量,当经过几次分组之后,记录的排列已经基本有序,这时再对所有记录实施直接插入排序。

注:时间复杂度为O(n1.3).

2.交换类排序

基本思想:在排序过程中,通过对待排序记录序列中的元素进行比较,如果发现次序相反,就将存储位置交换来达到排序的目的。

(1)冒泡排序

基本思想:两两比较相邻记录的关键字,如果反序则交换,直到没有反序的记录为止。

注:平均时间复杂度为O(n2).

(2)快速排序

基本思想:通过一趟排序将待排序记录分割成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序的目的。

注:平均时间复杂度为O(nlog2n).
3.选择类排序

基本思想:每一趟从待排序的记录中选出关键字最小的记录,顺序放在已排好序的记录序列的最后,直到全部排列完为止。

(1)简单选择排序

基本思想:第一趟从所有的n个记录中选择最小的记录放在第一位,第二趟从n-1个记录中选择最小的记录放在第二位,以此类推,经过n-1趟排序之后,整个待排序序列就成为有序序列了。

注:平均时间复杂度为O(n2).

(2)堆排序

堆:可以看成是一棵二叉树,其中每个非叶子节点的值均不大于(或不小于)其左、右孩子节点的值。

堆排序基本思想:首先将待排序的记录序列构造为一个堆,此时选择堆中所有记录的最小记录或最大记录,然后将它从堆中移出,并将剩余的记录再调整成堆,这样就又找到了次大(或次小)的记录。以此类推,直到堆中只有一个记录为止,每个记录出堆的顺序就是一个有序序列。

注:时间复杂度为O(nlog2n).

4.归并类排序

基本思想:将两个或两个以上有序的子序列合并成一个有序的序列。

(1)二路归并排序

基本思想:如果初始序列含有n个记录,则可以看成是n个有序的子序列,每个子序列的长度为1,然后两两归并,得到n/2个长度为2或1的有序子序列;再两两归并,……,如此重复,直至得到一个长度为n的有序序列为止

注:时间复杂度为O(nlog2n).

基本查找与排序的java代码实现如下:

import java.io.*;import java.util.*;/** * 排序与查找类 * */public class SearchingList {    private int[] list;    private StringTokenizer st;    private int number;    public SearchingList() throws IOException{        BufferedReader in=new BufferedReader(new InputStreamReader(System.in));        String line;        System.out.print("请输入元素总个数:");        this.number=Integer.parseInt(in.readLine());        this.list=new int[number];        System.out.println("请输入各元素,用空格隔开:");        line=in.readLine();        if(!line.isEmpty())            st=new StringTokenizer(line);        for(int i=0;i<this.number&&st.hasMoreTokens();i++){            this.list[i]=Integer.parseInt(st.nextToken());        }        System.out.println("原序列:");        this.output(list);        System.out.println();    }    /**     * 顺序查找     * 时间复杂度为O(n)     * @throws IOException     * @throws NumberFormatException     * */    public void dirSearch() throws NumberFormatException, IOException{        BufferedReader in=new BufferedReader(new InputStreamReader(System.in));        System.out.println("顺序查找:请输入所要查找的元素:");        int e = Integer.parseInt(in.readLine());        int k=0;        while(k<this.number&&this.list[k]!=e)        k++;        if(k<this.number)        System.out.println("在位置"+k+"找到元素"+e);        else         System.out.println("没有找到元素"+e);    }    /**     * 折半查找     * 前提是线性表是有序的     * 时间复杂度为O(logn)     * @throws IOException     * @throws NumberFormatException     * */    public void binSearch() throws NumberFormatException, IOException{        BufferedReader in=new BufferedReader(new InputStreamReader(System.in));        System.out.println("折半查找:请输入所要查找的元素:");        int e = Integer.parseInt(in.readLine());        int low = 1;         int high = this.number;        int mid,temp,t=0;        int[] list=this.copyList();        //排序(简单选择)        for(int i=0;i<this.number;i++){            int j = i;            for(int k = i+1;k<this.number;k++)                if(list[k]<list[j])                j=k;            if(j!=i){                temp=list[j];                list[j]=list[i];                list[i]=temp;            }        }        //查找        while(low <= high){               t++;               mid=(low + high)/2;               if(e==list[mid]){                   System.out.println("在第"+t+"趟找到元素"+e);//找到                   return;}               else if(e<list[mid])               high=mid-1;//左半区               else                low=mid+1;//右半区           }           System.out.println("没有找到元素"+e);    }    /**     * 直接插入排序     * 最好情况时间复杂度为O(n),最坏为O(n2)     * */    public void dirInsertionSort(){    int[] list=this.copyList();int i,j,temp;for(i = 1;i<list.length;i++){temp = list[i];              //这段表示前后两个元素 A与B,B的值放到temp中,当A值比temp大的时候,前面的元素即A,往后移动一个位置到B的位置for(j=i-1;j>=0 && list[j]>temp; j--){list[j+1] = list[j];  }list[j+1] = temp;   }this.output(list);        System.out.println();    }    /**     * 冒泡排序     * 平均时间复杂度为O(n2)     * */    public void bubbleSort(){        int temp,lastExchange,num = 1;        int i=this.number;        int[] list=this.copyList();        System.out.println("冒泡排序:");        while(i>1){            lastExchange=1;            for(int j=0;j<i;j++)                if(list[j]>list[j+1]){                    temp=list[j+1];                    list[j+1]=list[j];                    list[j]=temp;//交换元素                    lastExchange=j;//记下进行交换的记录位置                }            i=lastExchange;            //输出每一步的结果            System.out.print("第"+num+"趟:");            for(int k=0;k<this.number;k++)                System.out.print(list[k]+" ");            System.out.println();            num++;        }    }    /**     * 简单选择排序     * 平均时间复杂度为O(n2)     * */    public void simpleSelectSort(){        int j,k,temp;        int[] list=this.copyList();        System.out.println("简单选择排序:");        for(int i=0;i<this.number;i++){            j=i;            for(k=i+1;k<this.number;k++)                if(list[k]<list[j])                j=k;            if(j!=i){                temp=list[j];                list[j]=list[i];                list[i]=temp;            }            System.out.print("第"+i+"趟:");            this.output(list);            System.out.println();        }    }    /**序列的副本*/    private int[] copyList(){        int[] inlist=new int[this.number];        for(int i=0;i<this.number;i++){            inlist[i]=this.list[i];        }        return inlist;    }    /**输出序列*/    private void output(int[] list){        for(int i=0;i<this.number;i++){            System.out.print(list[i]+" ");        }    }} 




0 0
原创粉丝点击