廈大數據結構903歷年程序設計題

廈大數據結構2010年903 程序設計題
1.(15分)試用C語言編寫一個遍歷二叉查找樹的算法,要求遍歷過程剛好按照鍵值從大到小的次序進行.
解:
二叉查找樹(BST:Binary Search Tree)是一種特殊的二叉樹,它改善了二叉樹節點查找的效率。
二叉查找樹有如下性質:
(1)若左子樹不空,則左子樹上全部節點的值均小於它的根節點的值
(2)若右子樹不空,則右子樹上全部節點的值均大於它的根節點的值
(3)左、右子樹也分別爲二叉排序樹
(4)沒有鍵值相等的節點
所以,有如下數據結構定義:
typedef struct BSTreeNode{
    //數據域
    ElemType data;
    //遞歸定義 左右子樹
    struct BSTreeNode *left;
    struct BSTreeNode *right;
}BSTree;

void BSTreeSearch(tree *t){
    if (t == NULL) {
        return ;
    } else {
        BSTreeSearch(t->rchild);
        visit(t);
        BSTreeSearch(t->lchild);
    }
}


2.(15分)設L是一個帶頭結點的非遞減有序單鏈表的表頭指針.
試設計一個算法,將元素e插入到鏈表L中的合適地方,使得該鏈表還是非遞減有序.
解:
單鏈表的數據結構聲明:
typedef struct LinkList{
    ElemType data;
    LinkList *next;
}*L;

void insert(list &L, element a){
    L = L -> next;
    while (a > L -> data && a <= L-> next -> data){
        L = L -> next;
    }
    Node* newNode;
    newNode -> data = a;
    newNode -> next = L -> next;
    L -> next = newNode;
}


//插入新結點
void insert(LinkList * newNode){
    LinkList *temp = L;
    while (temp -> next != NULL) {
        if (temp -> next -> num > newNode -> num){
            break;
        }
        temp = temp -> next;
    }
    newNode -> next = temp -> next;
    temp -> next = newNode;
}

//打印列表
void output() {
    LinkList *p;
    p = L -> next;
    while (p != NULL){
        printf("%d\t", p->num);
    }
    printf("\n");
}


int main(){
    L = new LinkList;
    L -> next = NULL;
    L -> num = MAXN;
    int n;
    while(1){
        scanf("%d",&n);
        LinkList *now;
        now = new LinkList;
        now -> next = NULL;
        insert(now);
        output();
    }
    return 0;
}

//--------------------------------------------------------------//

廈大數據結構2011年903 程序設計題
1.(15分)有一個帶頭結點的單鏈表L = {a1,b1a2,b2,...,an,bn}.
請設計一個函數將其拆分爲兩個帶頭結點的單鏈表A和B,正序鏈表A= {a1,a2,..,an},
逆序鏈表B={bn,bn-1,...,b2,b1}.要求鏈表A使用鏈表L的頭結點.
[注]函數的頭部爲void split(LinkList *&L, LinkList *&A, LinkList *&B)
解:
typedef struct LinkList{
    ElemType data;
    LinkList *next;
}*L;


//頭插法拆分鏈表
void split(LinkList *&L, LinkList *&A, LinkList *&B){
    LinkList *p,*q;
    A = p = q = L;
    while (p -> next != NULL){
        q = p -> next -> next;
        p -> next -> next = q -> next;
        //彈出最近的B,插入到B鏈表的頭結點後
        q -> next = B -> next;
        B -> next = q;
        p = p -> next -> next;
    }
}


LinkList splitLinkList(LinkList &A){

    LinkList B = (LinkList) malloc (sizeof(NODE));
    B -> next = NULL;
    //p爲工做指針
    LinkList p = A -> next,q;
    LinkList ra = A;
    while (p){
        ra -> next = p;
        ra = p;
        //q是爲了防止斷鏈
        q = p -> next;
        p -> next = B -> next;
        B -> next = p;
        p = q;
    }
    ra -> next = NULL;
    return B;
}

.(15分)假設用單鏈表方式來存儲整數序列,以下形式:
[0| ] -> [3| ] -> [0| ] -> [3| ] -> [1| ] -> [3| ^]
請編寫一個遞歸算法,對這樣的鏈表進行處理,重複結點(值相同的結點).
僅保留排在最前面的一個,最後返回新鏈表的首地址.
例如,如有上述鏈表,則處理後的新鏈表以下:
[0| ] -> [3| ] -> [1|^]

解:
算法思想:從單鏈表的第一個結點開始,對每一個結點進行檢查:
檢查鏈表中該結點的全部後繼結點,只要有值和該結點的值相同,則刪除值;
而後檢查下一個結點,知道全部的結點都被檢查完.
typedef struct LNode {
    ElemType data;
    struct LNode *next;
}
//遞歸刪除以L爲頭結點的單鏈表中全部值相同的結點
void RecDelete_Node(LNode *L){
    if (L == NULL) return;
    LNode *pre = L;
    LNode *cur = pre -> next;
    while (cur!=NULL){
        if (cur->data == L->data){
            pre -> next = cur -> next;
            free(cur);
            cur = pre -> next;
        } else {
            pre = cur;
            cur = cur -> next;
        }
    }
    L = L -> next;
    RecDelete_Node(L);
}

//非遞歸算法
void IterDeleteNode(LNode *L){
    //刪除以單鏈表L中全部值相同的結點
    LNode *p = L,*q,*ptr;
    //刪除以單鏈表L中全部值相同的結點
    while (p != NULL) {
        q = p, ptr = p -> next;
        //檢測結點p的全部後繼結點ptr
        while (ptr != NULL) {
            if (ptr -> data = p -> data) {
                q -> next = ptr -> next;
                free(ptr);
                ptr = q -> next;
            } else {
                q = ptr;
                ptr = ptr -> next;
            }
        }
        p = p -> next;
    }
}




//--------------------------------------------------------------//


廈大數據結構2012年903 程序設計題
1.(15分)在一個遞增有序的線性表中,有數值相同的元素存在,若存儲方式爲單鏈表,
請設計算法去掉數值相同的元素,使表中再也不有重複的元素.
例如,下列線性表(7,10,10,21,30,42,42,42,61,70)
將變成(7,10,21,30,42,51,70)
請分析所設計算法的時間複雜度.
解:
數據結構定義:
typedef struct LinkList{
    ElemType data;
    LinkList *next;
}*L;

LinkList DeleteSameElem(LinkList &L){
    //表按照增序排列(從小到大),去掉相同元素,使得表中再也不有相同元素
    LNode *pre = L;
    LNode *p = L -> next;
    LNode *s = L;
    while (p != NULL) {
        if (pre -> data == p -> data){
            //防止斷鏈
            s = p;
            pre -> next = p -> next;
            p = p -> next;
            //釋放相同元素結點空間
            free(s);
        } else {
            //若不相等時,同時後移
            p = p -> next;
            pre = pre -> next;
        }
    }
    return L;
}


(2006年期末考卷A卷)
.(15分)試設計算法在O(n)時間內將數組A[0..n-1]劃分爲左右兩個部分,使得左邊的元素均爲
奇數,右邊的元素均爲偶數,要求所使用的輔助空間大小爲O(1).
解:
主要思路:
(1)設置兩個指針i和j,其中i=,j = n;
(2)當i < j時,做以下循環:
    i不斷自增 從左往右 找到第一個偶數
    j不斷自減 從左往右 找到第一個奇數
    A[i]和A[j],不斷交換
(3)算法結束
void Adjust (int a[], int n){
    int i = 0;
    int j = n -1;
    while (a[i]%2 != 0){
        i++
    }
    while (a[j]%j == 0){
        j++
    }
    if (i < j){
        int temp = a[i];
        a[i] = a[j];
        a[j] = temp;
    }
}

int main(){
    int a[6] = {1,3,2,4,8,6};
    Adjust(a,6);
    for (int i = 0; i < 6; i++){
        printf("%5d\n",a[i]);
    }
    return 0;
}



//--------------------------------------------------------------//



廈大數據結構2013年903 程序設計題
1.(15分)請利用兩個隊列Q1和Q2來模擬一個棧.
已知隊列的三個運算,定義以下:
bool EnQueue(Queue &Q, int e):插入一個元素e入隊列
bool DeQueue(Queue &Q, int &e):刪除一個元素e出隊列
bool QueueEmpty(Queue Q):判隊列爲空
假設數據結構Queue已定義,棧Stack的數據結構定義以下:
typedef struct{
    Queue Q1;
    Queue Q2;
}Stack;
請利用隊列的運算來實現該棧的三個運算:
Push(ST,x):元素x入ST棧
Pop(ST,x):ST棧頂元素出棧,賦給變量x
StackEmpty(ST):判ST棧是否爲空


void Push(Stack ST,element x) {
    element e;
    //把Q1中全部元素壓入Q2
    while (!QueueEmpty(ST.Q1)){
        //刪除Q1中準備被壓入Q2的元素
        DeQueue(ST.Q1,e);
        //把Q2取出來的元素壓入Q1隊列
        EnQueue(ST.Q2,e);
    }
    EnQueue(ST.Q1,x);
    while (!QueueEmpty(ST.Q2)) {
        //刪除Q2中準備被壓入Q1的元素
        DeQueue(ST.Q2,e);
        //把Q2取出來的元素壓入Q1隊列
        EnQueue(ST.Q1,e);
    }
}

//用隊列模擬出棧比入棧容易的多,因爲剛剛壓入的元素在隊列Q1的頭,
//只要彈出即爲彈棧操做
void Pop(Stack ST,element){
    element e;
    //隊列爲空,沒法完成彈棧
    if (QueueEmpty(ST.Q1)) return;
    DeQueue(ST.Q1,e);
}


bool StackEmpty(Stack ST){
    if (QueueEmpy()){
        return true;
    } else {
        false;
    }
}



2.(15分)下面小題與二叉樹的遍歷有關係:
(1)已知二叉樹的後序序列"abcdefg",同時已知二叉樹的中序序列"acbgdef",
是否能惟一肯定一棵二叉樹?若是能,請畫出二叉樹
(2)假設post[ps..ps+n-1]爲二叉樹的後序序列,ins[is..is+n-1]爲二叉樹的中序序列.
設計算法由兩個序列構造二叉樹的二叉鏈表.

解:(1)圖略
(2)程序以下:

BTNode *CreateBT(char *post, char *in, char *n) {
    BTNode *s;
    char *p;
    if (n <= 0) return NULL;
    s = (BTNode*)malloc(sizeof(NTNode));
    s -> data = *(post+(n-1));
    for (p = in; p < in+n; p++) {
        if (*p == *(post+(n-1))) break;
        k = p - in;
        s -> lchild = CreateBT(post,in,k); 
        s -> rchild = CreateBT(post,p+1,n-k-1);
    }
    return s;
}

Status CreateBiTree(BiTree &T) {
    scanf(&ch);
    if (ch == NULL) T = NULL;
    else {
        if ((!T=(BiTree*)malloc(sizeof(BiTNode)))) exit(OVERFLOW);
        T -> data = ch;
        CreateBiTree(T -> lchild);
        CreateBiTree(T -> rchild);
    }
    return OK;
}

//--------------------------------------------------------------//



廈大數據結構2014年903 程序設計題
1.(15分)判斷兩個非遞減有序的線性表中是否存在相同(關鍵字值相等)的元素,
若是相同的元素,返回第一個相同的元素在第一個有序表中的位置,不然返回0.
請合適的物理存儲結構,用C語言給出該物理存儲結構的類型定義,並在其上編寫算法.

typedef struct{
    ElemType *elem;
    int length;
    int listsize;
}List;

int judge(List A, List B){
    for (int i = 0; i < A.length; i++){
        int flag = 0;
        for (int j = 0; j < B.length; j++){
            if (A.elem[i] == B.elem[j]){
                flag = i;
                break;
            }
        }
    }
    return flag;
}


2.(15分)編寫函數判斷一棵二叉樹是否不含有度爲1的結點,若任何結點的度都不爲1,
則返回TRUE,不然返回FALSE,結點與二叉樹的數據結構以下:
typedef struct BiNode(){
    TElemType Data;
    //左右孩子指針
    struct BiTNode *lchild,*rchild;
} BiTNode,*BiTree;

程序設計以下:
int search(BiTNode *tree){
    if ((tree -> lchild == NULL && tree -> rchild != NULL) ||
        (tree -> rchild == NULL && tree -> lchild != NULL)){
        return false;
    } else {
        //判斷是葉子節點,什麼都不作
        if (tree -> lchild == NULL && tree -> rchild == NULL){

        } else {
            search(tree -> lchild);
            search(tree -> rchild);
        }
        //可以到達這一步說明全部節點就沒有單個孩子,則返回true;
        return true;
    }
}
//本題採用遞歸思想,非遞歸的思想也能實現.可是遞歸可以反應算法素養,每每能獲得更高的分.
//--------------------------------------------------------------//


廈大數據結構2015年903 程序設計題
1.(15分)在n個元素中,找到第k大的元素,用C語言寫出數據結構,設計算法實現上述要求,
並分析時間複雜性,最好是平均時間複雜度爲O(n).
解:
思路:尋找n個數中最大的k個數,本質上就是尋找最大的k個數中最小的那個,也就是第k大的數.
可使用二分搜索的策略來尋n個數中的第k大的數.
用數組a[max]做爲存儲數據結構,在數組a中查找.
算法代碼以下:
//快速排序的劃分函數
int partition(int a[], int l, int r){
    int i,j,x,temp;
    i = l;
    j = r + 1;
    x = a[l];
    //將>=x的元素換到左邊區域
    //將<=x的元素換到右邊區域
    while (1) {
        while (a[++i] > x);
        while (a[--j] < x);
        if (i >= j) break;
        temp = a[i];
        a[i] = a[j];
        a[j] = temp;
    }
    a[l] = a[j];
    a[j] = x;
    return j; 
}

//隨機劃分函數
int random_partition(int a[], int l,int r){
    //生產隨機數
    int i = l + rand()%(r-l+1);
    a[i] = a[l];
    a[l] = temp;
    //調用劃分函數
    return partition(a,l,r);
}

//線性尋找第 k 大的數

int random_select(int a[],int l,int r,int k){
    int i,j;
    if (l == r) //遞歸結束{
        return a[l];
    }
    i = random_partition(a,l,r);//劃分
    j = i-l+1;
    if(k == j) //遞歸結束,找到第 K 大的數
    return a[i];
    if(k < j) {
        //遞歸調用,在前面部分查找第k大的數
        return random_select(a,l,i-1,k);
    } else
    //遞歸調用,在後面部分查找第k大的數
    return random_select(a,i+1,r,k-j);
}


2.(15分)請用C語言寫出二叉樹的數據結構,並設計判斷兩個二叉樹是否相同(包括二叉樹的結構
以及每一個對應的結點的數據域data均相同)的算法.
解:
二叉樹的數據結構:
typedef struct bitree{
    int data;
    bitree *lchild;
    bitree *rchild;
}bitree;

int judgebitree(bitree *bt1, bitree *bt2){
    if (bt1 == 0 && bt2 == 0) return (1);
    else if (bt1 == 0 || bt2 == 0 || bt1 -> data != bt2 -> data){
        return (0);
    } else {
        return (judgebitree(bt1 -> lchild, bt2 -> lchild) && 
                judgebitree(bt1 -> rchild, bt2 -> rchild))
    }
}



//--------------------------------------------------------------//

(排列組合算法)
廈大數據結構2016年903 程序設計題
設計算法以求解從集合{1…n}中選取k(k<=n)個元素的全部組合。例如,從集合{14}中選取2個元素的全部組合的輸出結果爲:1 21 31 42 32 43 41.(15分)設計算法以求解從集合{1,n}中來選取k(k<=n)個元素的全部組合.
例如{1,4}中選取2個元素的全部組合的輸出結構爲1 2,1 3,1 4,2 3,2 4,3 4,
輸入:4 2
輸出:
1 2
1 3
1 4
2 3
2 4
3 4
函數的頭部爲Void print_combination(int n, int k)
void print_combination(int n, int k){
    a[k] = {1,2,3,4};
    if (n == k){
        for (int i = 0; i < k; i++){
            printf("%d\n",a[i]);
            printf("%d\n");
        }
    } else {
        for (int j = n; j < k; j++){
            print_combination(n+1,k);
            swap(&a[j], &a[index]);
        }
    }
}

void swap(int *p1, int *p2){
    int t = *p1;
    *p1 = *p2;
    *p2 = t;
}



2.(15分)在徹底二叉樹上,給定結點x,按照層次序打印結點x的全部子孫,請給出結點的數據結構和
算法,而且分析算法的時間複雜度.



//--------------------------------------------------------------//

廈大數據結構2017年903 程序設計題
1.(15分)寫出一個結點具備M個指針會的M對的數據結構,並設計一個遞歸算法計算M叉樹的深度.
其中M爲常量,設只有一個根節點的樹深度爲1,空樹深度爲0,計算嘗試函數的輸入爲節點指針和
M值.



2.一個僅由0,1,2三種數構成的數組A共有N個元素,亂序排列在一塊兒.
0,1,2的數量均大於0,但具體的個數未知,請設計一種時間複雜度爲O(n)的算法,
將數組排成以下形狀,0,01,12,2(即前面都是0,中間都是1,後面都是2)



//--------------------------------------------------------------//

廈大數據結構2018年903 程序設計題
1.(15分)描述下面這個算法,並用非遞歸形式來實現這個算法.
Status time (int &sum){
    int x;
    Scanf("%d\n",&x);
    if (x == 0){
        return sum = 1;
    } else {
        time(sum);
        sum *= x;
        printf("%d\n",&sum);
    }
    return OK;
}



2.寫二叉樹數據結構,葉子浮點型.
二叉樹中序遍歷3+4*5,設計算法實現這一計算過程.
相關文章
相關標籤/搜索