厦大数据结构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,设计算法实现这一计算过程.
相关文章
相关标签/搜索