1. 程式人生 > >資料結構經典例題解析C/C++程式碼實現(一)

資料結構經典例題解析C/C++程式碼實現(一)

考研需要吧,雖然挺基礎的,但是還是要練習下的,而且,還可以幫助一些其他同樣需要這些程式碼的朋友。

實現最基礎的資料結構建議是用C語言,這樣子很多細節都可以很好地把握,當然,如果用STL可以簡單地實現,那麼我也會實現一下。

第一題

題目

編一C程式,它能根據讀入的資料構造有向圖G,並輸出G的鄰接矩陣和鄰接表及G拓撲序列。圖的輸入形式為 i 0

   j 0    i 1    j 1
   i 2    j 2    . .
. &ThickSpace; i m &ThickSpace; j m &ThickSpace; 1 &ThickSpace; 1 i_0 \; j_0 \; i_1 \; j_1 \; i_2 \; j_2\; ...\; i_m\; j_m \; -1 \; -1 -1,-1為有向邊輸入結束標記,其餘的值都>= 0< n。), 它們都是整數,n是有向圖G的頂點個數且40 > n > 0,頂點名字依次是 V 0 , V 1 , V 2 , &ThickSpace; V n 1 V_0,V_1,V_2,…\; V_{n-1} i k &ThickSpace; j k i_k \; j_k 表示向圖G的有向邊 &lt; V i k , V j k &gt; &lt;V_{i_k},V_{j_k}&gt;

解析

鄰接矩陣和鄰接表是圖論中的基礎,那麼在程式碼中如何表示,這是一個基礎;

拓撲序列牽扯到拓撲排序,這個還是要了解下的。

C語言

#define MAX_SIZE 50

int buff[MAX_SIZE << 1];

int adjacencyMatrix[MAX_SIZE][MAX_SIZE];

int head[MAX_SIZE];

typedef struct
{
    int to, next;
} Edge;

int n, m;

Edge edges[MAX_SIZE * MAX_SIZE];

void GetAdjacencyMatrix(int m)
{
    int i;

    memset(adjacencyMatrix, 0, sizeof(adjacencyMatrix));

    for (i = 0; i < 2 * m; i += 2) {
        adjacencyMatrix[buff[i]][buff[i + 1]] = 1;
    }
}

void GetAdjacencyTable(int m)
{
    int i;

    memset(head, -1, sizeof(head));

    for (i = 0; i < 2 * m ; i += 2) {
        edges[i] = {buff[i + 1], head[buff[i]]};
        head[buff[i]] = i >> 1;
    }
}

void PrintAdjacencyMatrix(int n)
{
    int i, j;

    for (i = 0; i < n; ++i)
        for (j = 0; j < n; j++)
            printf("%d%c", adjacencyMatrix[i][j], " \n"[j + 1 == n]);

    puts("");
}

void PrintAdjacencyTable(int n)
{
    int i, j;

    for (i = 0; i < n; ++i) {
        printf("%d : ", i);
        for (j = head[i]; j + 1; j = edges[j].next)
            printf("%d%c", edges[j].to, " \n"[edges[j].next + 1 == 0]);
    }

    puts("");
}

int in[MAX_SIZE];

// using adjacency matrix
int TopologicalSort(int n)
{
    int res[MAX_SIZE], used[MAX_SIZE];
    int index = 0;
    int i, j;

    memset(in, 0, sizeof(in));
    memset(used, 0, sizeof(used));
    for (i = 0; i < n; ++i)
        for (j = 0; j < n; ++j)
            in[j] += adjacencyMatrix[i][j];

    do {
        for (i = 0; i < n; ++i)
            if (!in[i] && !used[i])
                break;
        if (i == n)
            return -1;

        used[i] = 1;
        res[index++] = i;

        for (j = 0; j < n; ++j)
            in[j] -= adjacencyMatrix[i][j];

    } while (index != n);

    for (i = 0; i < n; printf("%d%c", res[i], " \n"[i + 1 == n]), ++i) {}

    return 0;
}

int main()
{
    int i;
    int x, y;

    scanf("%d", &n);
    for (m = 0, i = 0; scanf("%d%d", &x, &y) && x + 1 && y + 1; ++m, i += 2)
        buff[i] = x, buff[i + 1] = y;

    GetAdjacencyMatrix(m);
    GetAdjacencyTable(m);

    PrintAdjacencyMatrix(n);
    PrintAdjacencyTable(n);

    TopologicalSort(n);

    return 0;
}

C++

C++的std::vector可以很容易實現鄰接表,這個可以實現下


std::vector<int> head[MAX_SIZE];

void GetAdjacencyTable(int m)
{
    for (int i = 0; i < m; ++i)
        head[buff[i]].push_back(buff[i + 1]);
}

第二題

題目

編一C程式,它能讀入兩組整數(每組整數都以-9999為結束標記,個數都不大於1000),並以從小到大的次序輸出既在第一組整數中也在第二組整數中的所有整數(同一個整數不能輸出兩次)。(輸入時,兩個相鄰的整數用空格隔開)。

解析

C語言

#define MAX_SIZE 1000

#define END -9999

int n, m;
int arrayN[MAX_SIZE], arrayM[MAX_SIZE];
int res[MAX_SIZE], index;

int cmp(const void *a, const void *b)
{
    return *(const int *)a - *(const int *)b;
}

void GetAns()
{
    int p1, p2;

    qsort(arrayN, n, sizeof(arrayN[0]), cmp);
    qsort(arrayM, m, sizeof(arrayM[0]), cmp);

    for (p1 = p2 = index = 0; p1 < n && p2 < m; ) {
        if (arrayN[p1] == arrayM[p2])
            res[index++] = arrayN[p1], ++p1, ++p2;
        else
            arrayN[p1] < arrayM[p2] ? ++p1 : ++p2;
    }
}

int main()
{
    int x, i;

    for (n = 0; scanf("%d", &x) && x != END; arrayN[n++] = x) {}
    for (m = 0; scanf("%d", &x) && x != END; arrayM[m++] = x) {}

    GetAns();

    for (i = 0; i < index; printf("%d%c", res[i], " \n"[i + 1 == index]), ++i);

    return 0;
}

C++

C++的sort比C語言中的qsort好用;

這種類似求交集的運算,STL中提供了std::set_intersection,具體參考圖解STL中演算法的分類、簡介及其Demo

#include <bits/stdc++.h>

#define END -9999

std::vector<int> arrayN, arrayM, res;

void GetAns()
{
    std::sort(arrayN.begin(), arrayN.end());
    std::sort(arrayM.begin(), arrayM.end());

    std::set_intersection(arrayN.begin(), arrayN.end(),
                            arrayM.begin(), arrayM.end(),
                            std::back_inserter(res));
}

int main()
{
    for (int x; std::cin >> x && x != END; arrayN.push_back(x)) {}
    for (int x; std::cin >> x && x != END; arrayM.push_back(x)) {}

    GetAns();

    for (auto it = res.begin(); it != res.end();
            std::cout << *it << " \n"[it + 1 == res.end()], ++it) {}

    return 0;
}