2022年王道数据结构考研复习指导习题代码(排序)

8.3交换排序
2.编写双向冒泡算法,在正反两个方向交替进行扫描,即第一趟把关键字最大的元素放在序列的最后面,第二趟把关键字最小的元素放在序列的最前面,如此反复进行。

#include <iostream>
#include <algorithm>
using namespace std;

typedef int ElemType;

ElemType a[50];

void BubbleSort(ElemType a[], int n)
{
    int low = 0, high = n - 1, i;
    bool flag = true;
    while (low < high && flag) {
        flag = false;
        for (i = low; i < high; i++) {
            if (a[i] > a[i + 1]) {
                swap(a[i], a[i + 1]);
                flag = true;
            }
        }
        high--;
        for (i = high; i > low; i--) {
            if (a[i] < a[i - 1]) {
                swap(a[i], a[i - 1]);
                flag = true;
            }
        }
        low++;
    }
}

int main()
{
    int n;
    cin >> n;
    for (int i = 0; i < n; i++) cin >> a[i];
    BubbleSort(a, n);
    for (int i = 0; i < n; i++) cout << a[i] << " ";
    cout << endl;
    return 0;
}

3.已知线性表按顺序存储,且每个元素都是不相同的整形元素,设计把所有奇数移动到所有偶数前边的算法(要求时间最少,辅助空间最少)。

#include <iostream>
#include <algorithm>
using namespace std;

typedef int ElemType;

ElemType A[50];

void move(ElemType A[], int len)
{
    int i = 0, j = len - 1;
    while (i < j) {
        while (i < j && A[i] % 2 != 0) i++;
        while (i < j && A[j] % 2 != 1) j--;
        if (i < j) {
            swap(A[i], A[j]);
            i++; j--;
        }
    }
}

int main()
{
    int n;
    cin >> n;
    for (int i = 0; i < n; i++) cin >> A[i];
    move(A, n);
    for (int i = 0; i < n; i++) cout << A[i] << " ";
    cout << endl;
    return 0;
}

4.试重新编写考点精析中的快速排序的划分算法,使之美词选取的枢轴值都是随机地从当前子表中选择的。

#include <cstdlib>
#include <iostream>
using namespace std;

typedef int ElemType;

ElemType A[50];

int Partition2(ElemType A[], int low, int high)
{
    int rand_Index = low + rand() % (high - low);
    swap(A[rand_Index], A[low]);
    ElemType pivot = A[low];
    int i = low;
    for (int j = low + 1; j <= high; j++)
        if (A[j] < pivot) swap(A[++i], A[j]);
    swap(A[i], A[low]);
    return i;
}

void QuickSort(ElemType A[], int low, int high)
{
    if (low < high) {
        int pivotpos = Partition2(A, low, high);
        QuickSort(A, low, pivotpos - 1);
        QuickSort(A, pivotpos + 1, high);
    }
}

int main()
{
    int n;
    cin >> n;
    for (int i = 1; i <= n; i++) cin >> A[i];
    QuickSort(A, 1, n);
    for (int i = 1; i <= n; i++) cout << A[i] << " ";
    cout << endl;
    return 0;
}

5.试编写一个算法,使之能够在数组L[1…n]中找出第k小的元素(即从小到大排序后处于第k个位置的元素)。

#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;

int a[50];

int kth_elem(int a[], int low, int high, int k)
{
    int rand_Index = low + rand() % (high - low + 1);
    swap(a[rand_Index], a[low]);
    int pivot = a[low];
    int low_temp = low; int high_temp = high;
    while (low < high) {
        while (low < high && a[high] >= pivot) --high;
        a[low] = a[high];
        while (low < high && a[low] <= pivot) ++low;
        a[high] = a[low];
    }
    a[low] = pivot;
    if (low == k) return a[low];
    else if (low > k) return kth_elem(a, low_temp, low - 1, k);
    else return kth_elem(a, low + 1, high_temp, k);
}

int main()
{
    int n, k;
    cin >> n;
    for (int i = 1; i <= n; i++) cin >> a[i];
    cin >> k;
    int ans =  kth_elem(a, 1, n, k);
    cout << ans << endl;
    return 0;
}

6.已知由 n ( n ≥ 2 ) n(n \geq 2) n(n2)个正整数构成的集合 A = a k ∣ 0 ≤ k < n A={a_{k}|0 \leq k < n} A=ak0k<n,将其划分为两个不相交的子集 A 1 A_{1} A1 A 2 A_{2} A2,元素个数分别是 n 1 n_{1} n1 n 2 n_{2} n2 A 1 A_{1} A1 A 2 A_{2} A2中的元素之和分别为 S 1 S_{1} S1 S 2 S_{2} S2。设计一个尽可能高效的划分算法,满足 ∣ n 1 − n 2 ∣ |n_{1}-n_{2}| n1n2最小且 ∣ S 1 − S 2 ∣ |S_{1}-S_{2}| S1S2最大。

#include <iostream>
using namespace std;

int a[50];

int setPartition(int a[], int n)
{
    int pivotkey, low = 0, low0 = 0, high = n - 1, high0 = n - 1, flag = 1, k = n / 2, i;
    int s1 = 0, s2 = 0;
    while (flag) {
        pivotkey = a[low];
        while (low < high) {
            while (low < high && a[high] >= pivotkey) --high;
            if (low != high) a[low] = a[high];
            while (low < high && a[low] <= pivotkey) ++low;
            if (low != high) a[high] = a[low];
        }
        a[low] = pivotkey;
        if (low == k - 1) flag = 0;
        else {
            if (low < k - 1) {
                low0 = ++low;
                high = high0;
            } else {
                high0 = --high;
                low = low0;
            }
        }
    }
    for (i = 0; i < k; i++) s1 += a[i];
    for (i = k; i < n; i++) s2 += a[i];
    return s2 - s1;
}

int main()
{
    int n;
    cin >> n;
    for (int i = 0; i < n; i++) cin >> a[i];
    int ans = setPartition(a, n);
    cout << ans << endl;
    return 0;
}

7.荷兰国旗问题:设有一个仅有红、白、蓝三种颜色的条块组成的条块序列,请编写一个时间复杂度为 Q ( n ) Q(n) Q(n)的算法,使得这些条块按红、白、蓝的顺序排好,即排成荷兰国旗图案。

#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;

char a[50];

void Flag_Arrange(char a[], int n)
{
    int i = 0, j = 0, k = n - 1;
    while (j <= k) {
        switch (a[j]) {
            case 'R': swap(a[i], a[j]); i++; j++; break;
            case 'W': j++; break;
            case 'B': swap(a[j], a[k]); k--;
        }
    }
}

int main()
{
    cin >> a;
    int n = strlen(a);
    Flag_Arrange(a, n);
    for (int i = 0; i < n; i++) cout << a[i];
    return 0;
}

8.4选择排序
4.编写一个算法,在基于单链表表示的带排序关键字序列上进行简单选择排序。

#include <stdio.h>
#include <stdlib.h>

typedef int ElemType;

typedef struct LinkNode {
    ElemType data;
    struct LinkNode *link;
} LinkNode, *LinkedList;

LinkedList init()
{
    LinkedList head = (LinkedList)malloc(sizeof(LinkNode));
    int n;
    ElemType x;
    scanf("%d", &n);
    scanf("%d", &x);
    head->data = x;
    head->link = NULL;
    LinkNode *tail = head;
    for (int i = 1; i < n; i++) {
        LinkedList temp = (LinkedList)malloc(sizeof(LinkNode));
        scanf("%d", &x);
        temp->data = x;
        tail->link = temp;
        temp->link = NULL;
        tail = tail->link;
    }
    return head;
}

void selectSort(LinkedList &L)
{
    LinkNode *h = L, *p, *q, *r, *s;
    L = NULL;
    while (h != NULL) {
        p = s = h; q = r = NULL;
        while (p != NULL) {
            if (p->data > s->data) {
                s = p;
                r = q;
            }
            q = p;
            p = p->link;
        }
        if (s == h) h = h->link;
        else r->link = s->link;
        s->link = L;
        L = s;
    }
}

void printList(LinkedList L)
{
    while (L) {
        printf("%d ", L->data);
        L = L->link;
    }
    printf("\n");
}

int main()
{
    LinkedList L = init();
    selectSort(L);
    printList(L);
    return 0;
}

5.试设计一个算法,判断一个数据序列是够构成一个小根堆。

#include <iostream>
using namespace std;

typedef int ElemType;

ElemType A[50];

bool IsMinHeap(ElemType A[], int len)
{
    if (len % 2 == 0) {
        if (A[len / 2] > A[len]) return false;
        for (int i = len / 2 - 1; i >= 1; i--)
            if (A[i] > A[2 * i] || A[i] > A[2 * i + 1]) return false;
    } else {
        for (int i = len / 2; i >= 1; i--)
            if (A[i] > A[2 * i] || A[i] > A[2 * i + 1]) return false;
    }
    return true;
}

int main()
{
    int n;
    cin >> n;
    for (int i = 1; i <= n; i++) cin >> A[i];
    if (IsMinHeap(A, n)) cout << "Yes" << endl;
    else cout << "No" << endl;
    return 0;
}

8.6各种内部排序算法的比较与应用
4.设有一个数组中存放了一个无序的关键序列 K 1 , K 2 , … , K n K_{1},K_{2},…,K_{n} K1,K2,,Kn。现要求将 K n K_{n} Kn放在将元素排序后的正确位置上,试编写实现该功能的算法,要求比较关键字的次数不超过 n n n

#include <iostream>
using namespace std;

typedef int ElemType;

ElemType K[20];

int Partition(ElemType K[], int n)
{
    int i = 1, j = n;
    ElemType pivot = K[j];
    while (i < j) {
        while (i < j && K[i] <= pivot) i++;
        if (i < j) K[j] = K[i];
        while (i < j && K[j] >= pivot) j--;
        if (i < j) K[i] = K[j];
    }
    K[i] = pivot;
    return i;
}

int main()
{
    int n;
    cin >> n;
    for (int i = 1; i <= n; i++) cin >> K[i];
    int p = Partition(K, n);
    cout << p << endl;
    return 0;
}
  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值