厦大数据结构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; } 2.(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卷) 2.(15分)试设计算法在O(n)时间内将数组A[0..n-1]划分为左右两个部分,使得左边的元素均为 奇数,右边的元素均为偶数,要求所使用的辅助空间大小为O(1). 解: 主要思路: (1)设置两个指针i和j,其中i=1,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; } }
厦大数据结构903历年程序设计题
猜你喜欢
转载自www.cnblogs.com/lx17746071609/p/11733966.html
今日推荐
周排行