头歌数据结构与算法——实验四:查找和排序

1,164 阅读6分钟

第一关 折半查找

任务描述
本关任务:实现折半查找的递归与非递归算法

编程要求
输入
多行数据
第一行是顺序表长度n
第二行是顺序表内的元素信息
第三行是待查找元素key

输出
两行数据
分别是折半查找递归算法查找结果和折半查找非递归算法查找结果,若元素不存在返回0

测试说明
平台会对你编写的代码进行测试:

测试输入:
8
2 4 6 8 10 12 14 16
6

预期输出:
3
3
#include<iostream>
using namespace std;

typedef struct SSTable
{
	int *R;			 //顺序表基地址,元素存储位置为[1..length]				
	int length;								
}SSTable;					

int BinSearch_recur(SSTable ST,int key,int low,int high)
{		
    //实现折半查找递归算法,查找成功返回元素所在位置,查找失败返回0
    //在此处填入代码
    int mid = (low + high)/2;

    if(low > high){
        return 0;
    }

    if(ST.R[mid] == key){
        return mid;
    }else if(ST.R[mid] > key){
        return BinSearch_recur(ST,key,low,mid-1);
    }else{
        return BinSearch_recur(ST,key,mid+1,high);
    }
    
	
}

int BinSearch_norecur(SSTable ST,int key,int low,int high)
{		
    //实现折半查找非递归算法,查找成功返回元素所在位置,查找失败返回0
    //在此处填入代码
    int mid = (low + high)/2;
    
    while(low <= high){
        int mid = (low + high)/2;
        if(ST.R[mid] == key){
            return mid;
        }else if(ST.R[mid] > key){
            high = mid - 1;
        }else{
            low = mid + 1;
        }
    }
	
    return 0;


}

第二关 二叉排序树

任务描述
本关任务:实现二叉排序树中的递归查找与非递归查找算法

编程要求
输入
多行数据
第一行是二叉排序树元素个数
第二行是构造二叉排序树时的待插入元素序列
第三行是待查找元素key

输出
两行数据
若查找成功,分别输出:
递归查找成功
非递归查找成功
若查找失败,分别输出
递归查找失败
非递归查找失败

测试说明
平台会对你编写的代码进行测试:

测试输入:
8
8 10 6 4 2 12 16 14
6

预期输出:
递归查找成功
非递归查找成功
#include<iostream>
using namespace std;

typedef struct BSTNode
{
	int data;
	struct BSTNode *lchild,*rchild;
}BSTNode,*BSTree;

BSTNode* SearchBST_cur(BSTree T,int key)
{
    //实现二叉排序树中的递归查找,返回值为key的结点指针,若不存在则返回NULL
    //在此处填入代码

    if(T == NULL){
        return NULL;
    }

    if(T->data == key){
        return T;
    }else if(T->data > key){
        return SearchBST_cur(T->lchild,key);
    }else{
        return SearchBST_cur(T->rchild,key);
    }


}

BSTNode* SearchBST_nocur(BSTree T,int key)
{
     //实现二叉排序树中的非递归查找,返回值为key的结点指针,若不存在则返回NULL
    //在此处填入代码

    while(T != NULL){

        if(T->data == key){
            return T;
        }else if(T->data > key){
            T = T->lchild;
        }else{
            T = T->rchild;
        }
    }

    return NULL;
}

第三关 插入排序与选择排序

任务描述
本关任务:实现在顺序表上的直接插入排序与简单选择排序算法

编程要求
输入
两行数据
第一行是顺序表元素个数n
第二行是顺序表内所有元素

输出
两行数据
分别是直接插入排序后的结果和简单选择排序后的结果

测试说明
平台会对你编写的代码进行测试:

测试输入:
8
3 6 7 1 4 2 5 8

预期输出:
直接插入排序后的结果为:1 2 3 4 5 6 7 8
简单选择排序后的结果为:1 2 3 4 5 6 7 8
#include<iostream>
using namespace std;
#define MAXSIZE 100
#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef int Status;

typedef struct SqList
{
	int *R;		//顺序表基地址,元素存储位置为[1..length]						
	int length;								
}SqList;						

void InsertSort(SqList &L)
{
	//对顺序表L进行直接插入排序
	// 请在此编写代码
    for(int i = 2;i <= L.length;i++){
        if(L.R[i] < L.R[i-1]){
            L.R[0] = L.R[i];
            L.R[i] = L.R[i-1];
            int j;
            for(j = i-2;L.R[0] < L.R[j];j--){
                L.R[j+1] = L.R[j];
            }
            L.R[j+1] = L.R[0];
        }
    }
	

}

void SelectSort(SqList &L)
{
	//对顺序表L进行简单选择排序
	//请在此编写代码
    for(int i = 1;i < L.length;i++){
        int k = i;
        for(int j = i + 1;j <= L.length;j++){
            if(L.R[j] < L.R[k]){
                k = j;
            }
        }

        if(k != i){
            int temp = L.R[i];
            L.R[i] = L.R[k];
            L.R[k] = temp;
        }

    }
	
	
}

第四关 快速排序

任务描述
本关任务:实现在顺序表上的快速排序算法

编程要求
输入
两行数据
第一行是顺序表元素个数n
第二行是顺序表内所有元素

输出
快速排序后结果

测试说明
平台会对你编写的代码进行测试:

测试输入:
8
3 6 7 1 4 2 5 8

预期输出:
1 2 3 4 5 6 7 8
#include<iostream>
using namespace std;
#define MAXSIZE 100
#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef int Status;

typedef struct SqList
{
	int *R;		//顺序表基地址,元素存储位置为[1..length]						
	int length;								
}SqList;						

int Partition(SqList &L,int low,int high)						
{
	//实现快速排序的划分算法
	//在此写入代码
    L.R[0] = L.R[low];
    while(low < high){
        while(low < high && L.R[high] >= L.R[0]){
            high--;
        }
        L.R[low] = L.R[high];
        while(low < high && L.R[low] <= L.R[0]){
            low++;
        }
        L.R[high] = L.R[low];
    }
    L.R[low] = L.R[0];
    return low;
    
}

void QSort(SqList &L,int low,int high)						
{
	//实现快速排序算法,对顺序表L[low..high]进行快速排序
	//在此写入代码

    if(low < high){
        int pivotloc = Partition(L,low,high);
        QSort(L,low,pivotloc-1);
        QSort(L,pivotloc+1,high);
    }
    
	
}

第五关 奇偶元素移动

任务描述
本关任务:已知一个顺序表内都是不相同的整数型元素,设计一个算法,把所有奇数移动到所有偶数前边,要求时间效率最高,辅助空间最小
提示:参考快速排序partition算法

编程要求
输入
两行数据
第一行是顺序表元素个数n
第二行是顺序表内所有元素

输出
元素移动后的检验结果

测试说明
平台会对你编写的代码进行测试,若成功移动,输出“移动成功”,若移动后无法保证所有奇数在偶数之前,输出“移动失败”

测试输入:
8
3 6 7 1 4 2 5 8

预期输出:
移动成功
#include<iostream>
using namespace std;
#define MAXSIZE 100
#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef int Status;

typedef struct SqList
{
	int *R;		//顺序表基地址,元素存储位置为[1..length]						
	int length;								
}SqList;						

void move(SqList L)
{
	//将顺序表所有的奇数都移动到偶数之前
	//在此写入代码
    int low = 1;
    int high = L.length;

    while(low < high){
        while(L.R[low]%2 != 0 && low < high){
            low++;
        }
        while(L.R[high]%2 == 0 && low < high){
            high--;
        }
        
        int temp = L.R[low];
        L.R[low] = L.R[high];
        L.R[high] = temp;
        low++;
        high++;
    }
	
	
}

第六关 第k小的数

任务描述
本关任务:设计一个算法,在无序顺序表内查找第k小的元素,返回第k小元素的值,要求时间复杂度尽可能低
提示:参考快速排序过程

编程要求
输入
三行数据
第一行是顺序表元素个数n
第二行是顺序表内所有元素
第三行是第k小的k

输出
第k小的元素的值

测试说明
平台会对你编写的代码进行测试

测试输入:
8
3 6 7 1 4 2 5 8
4

预期输出:
4
#include<iostream>
using namespace std;
#define MAXSIZE 100
#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef int Status;

typedef struct SqList
{
	int *R;		//顺序表基地址,元素存储位置为[1..length]						
	int length;								
}SqList;						



int kth_elem(SqList L,int k)
{
	//实现函数,返回顺序表内第k小的元素的值,若不存在返回-1
	//在此处填入代码
     if (k < 1 || k > L.length){
        return -1;
     }

    int left = 1;
    int right = L.length;

    while (left <= right){
        int pivot = L.R[left];
        int i = left;
        int j = right;
        while (i < j){
            while (i < j && L.R[j] >= pivot){
                j--;
            }
            L.R[i] = L.R[j];

            while (i < j && L.R[i] <= pivot){
                i++;
            }
            L.R[j] = L.R[i];
        }
        L.R[i] = pivot;
        if (i == k){
            return L.R[i];
        }else if(i < k){
            left = i + 1;
        }else{
            right = i - 1;
        }

    }
    return -1;
}

//可以在函数外定义其他函数进行调用

    ```