数据结构1

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

一、((本题15分)试设计一个结点数据类型为整型的带表头结点的有序单

链表,然后设计一个算法,该算法将这个有序单链表划分成两个单链表,使得第一个单链表中包含原单链表中所有数值为奇数的结点,第二个单链表中包含原单链表中所有数值为偶数的结点,且两个单链表中结点的相对排列顺序与原单链表中相同。注意:要求使用原单链表的空间,表头结点可以另辟空间。

[解答]

void split(LinkList &HL, LinkList &L1, LinkList &L2) {

q1=L1= (LinkList) malloc(sizeof(LNode));

q2=L2= (LinkList) malloc(sizeof(LNode));

p=HL->next;

while (p!=NULL) {

if (p->date % 2 != 0) {

q1->next= p; q1=p;}

else

q2->next= p; q2=p;}

p=p->next;

}

q1->next=q2->next=NULL;

free(HL);

}

二、(本题20分)试设计一个递归算法,判断二叉树T是否是满二叉树,假

设T是以二叉链表存储。

typedef struct BiTNode{

TElemType data;

Struct BiTNode *lchild, *rchild;

} BiTNode, *BiTree;

解答:

满二叉树中任一个结点为根的子树都是满二叉树。

算法:

(1)如果二叉树T是空树,则是满二叉树;

(2)如果二叉树T非空,左右子树都是满二叉树,而且深度一样,则T是满二叉树;(3)如果二叉树T非空,左子树或右子树不是满二叉树,则不是满二叉树;

(4)如果二叉树T非空,左右子树都是满二叉树,但深度不一样,则T不是满二叉树。//该函数判断二叉树T是否是满二叉树

//如果是满二叉树,返回TRUE,Depth返回该树的深度;

//否则返回FALSE,Depth无定义;

Boolean Check( BiTree T, int &Depth)

{ int ldepth, rdepth;

if( T==NULL) { Depth=0; return TRUE; }

if( Check(T->lchild, ldepth)==FALSE ) return FALSE;

if( Check(T->rchild,rdepth)==FALSE) return FALSE;

if( ldepth!=rdepth ) return FALSE;

Depth=ldepth+1; return TRUE;

}

三、(本题15分)试设计算法在O(n)时间内将数组A[1..n]划分为左右两个

部分,使得左边的所有元素为奇数,右边的所有元素均为偶数,要求所使用的辅助存储空间大小为O(1)。

解:该题算法的主要思路如下:

(1)设置两个指针i和j,其中i=1,j=n。

(2)当i

i不断自加从左往右找到第一个偶数

j不断自减从右往左找到第一个奇数

A[i]与A[j]交换

(3)算法结束

Adjust(int A[1..n])

{

int i=1, j=n;

while (i

while (A[i] % 2 != 0 && i<=n) i++;

while (A[i] % 2 = =0 && j>=1) j--;

if (i>n || j<1) break;

if (i

}

}

算法的时间复杂性为O(n),辅助存储空间为O(1)。

应采用堆排序,因为当给定的待排序的记录的关键字基本有序时,快速排序将退化为起泡排序,此情况下的快速排序时间复杂度为O(n2),而堆排序即便在最坏情况下的时间复杂度仍为O(nlogn)。

四、本题10分)给定广义表(a,((),b),(((e)))),完成下列要求:

1)给出广义表的数据结构;

2)画出该广义表的存储结构图;

3)利用取表头和表尾的操作分离出原子e(给出GetHead、GetTail的操作序列)。

[解答]

1)(见课本P109~110)

2)

3)令给定广义表为L,则Gethed(GetHead(GetHead(GetHead(GetTail(Gettail(L)))))

五、(本题15分)试设计一个带头结点的单链表,然后写一个算法将该单链

表逆转,要求利用原表结点空间,不允许申请和使用新的结点空间。

解:

方法一:建立一个新的单链表,其中的结点从原表得来,即每个原表中得到一个结点,就要将此结点插入新链表中。由于要将表逆转,原表的头结点成为新链表的头结点,每次从原表中得到一个结点,此结点插在头结点之后,作为新链表的第一个结点。

void InverLinkedList( LinkList &L){

LNode *p, *s;

P=L→next;

L→next=NULL;

while (p) {

s=p; //p为待逆置链表头指针

p=p→next; //从p所指链表中删除第一个结点

s→next=L→next;

L→next=s; //将s结点插入到逆置表的表头

}

}

方法二:在遍历原表的时候将各结点的指针逆转,从原表的第一个结点开始,表头结点的指针在最后修改成指向原表的最后一个结点。

void InvertLinkedList( LinkList &L) {

LNode *p, *q;

S=L→next;

if (s) {

q=NULL;

p=s;

while (p) {

p=p→next;

相关文档
最新文档