一些东华自命题考研算法题

1.试编写算法,对一棵以孩子-兄弟链表表示的一般树统计其叶子的个数。

#include
using namespace std;
struct Node{	//左孩子,右兄弟表示法
	struct Node* child,*sibling;
};
typedef Node* Tree;
int counts=0;
void NumberOfLeaf(Tree root){// recursive
	if(root==NULL) return;
	if(root->child==NULL) counts++;
	NumberOfLeaf(root->child);
	NumberOfLeaf(root->sibling);
}

/*1.试编写算法,对一棵以孩子-兄弟链表表示的一般树统计其叶子的个数。*/

2.试编写算法,将单链表L1拆成两个链表,其中以L1为头的链表保持原来向后的链接,另一个链表的头为L2,其链表方向与L1相反,
L1包含原链表的奇数序号的节点,L2包含原链表的偶数序号的节点。

#include
#include
using namespace std;
struct Node{	//单链表
	int data;
	struct Node* next;
};
typedef Node* List;
void SplitList(List head,Node* &head1,Node* &head2){
	vector v;
	if(head==NULL) return;
	head=head->next;
	while(head){//将头结点以外的所有节点顺序放进去
		v.push_back(head);
		head=head->next;
	}
	head1=new Node,head2=new Node;
	Node* tmp1=head1,*tmp2=head2;
	for(int i=1;inext=v[i];
		tmp1=tmp1->next;
	}
	tmp1->next=NULL;

	int i=v.size();
	if(i%2==0) i--; 
	i--;
	for( ;i>=0;i=i-2){
		tmp2->next=v[i];
		tmp2=tmp2->next;
	}
	tmp2->next=NULL;
	
}
//答题需要的代码到此结束
//下面用于本地验证
Node* GenerateAList(){//带有头结点
	Node*head=new Node;
	Node* tmp=head;
	for(int i=0;i<10;i++){
		tmp->next=new Node;
		tmp=tmp->next;
		tmp->data=i;
	}
	tmp->next=NULL;
	return head;
}
void Show(List head){
	if(head==NULL) return;
	head=head->next;
	while(head){
		coutnext;
	}
	cout<

3.设有一个含n(n>1)个整数的线性表。请设计一个在时空两方面尽可能高效的算法,将表中数据从小到大重新排序。要求:
(1)给出算法的基本设计思想。
(2)采用类C语言描述算法,关键步骤给出注释,说明时间复杂度和空间复杂度。
详见《排序概述》
http://blog.csdn.net/chuchus/article/details/39379287

4.已知二叉树T采用二叉链表存储结构,每个节点有三个字段,内容、左孩子指针、右孩子指针。
请设计一个计算该二叉树所有叶子节点数目的算法。

注意与1题的区别与联系。

#include
using namespace std;
struct Node{	//二叉树结点
	int data;
	struct Node* lchild,*rchild;
};
typedef Node* Tree;
int counts=0;
void NumberOfLeaf(Tree root){// recursive
	if(root==NULL) return;
	if(root->lchild==NULL&&root->rchild==NULL) counts++;
	NumberOfLeaf(root->lchild);
	NumberOfLeaf(root->rchild);
}
5.有一个非严格递增单链表,设计一个算法删除值重复的节点。
#include
#include
using namespace std;
typedef struct node
{
    int data;
    struct node* next;
    node(){next=NULL;}
    node(int x){next=NULL;data=x;}
}*List;
void DeleteRepeatElements(List l){
    if(!l|| l->next==NULL) return;
    List i,j; i=l->next;j=i->next;
    while(j){
        if(i->data==j->data) {
            j=j->next;delete i->next; i->next=j;
        }
        else{
             j=j->next; i=i->next;
        }
    }

}
//以上为卷面作答内容   下面为自己验证用
 List l=NULL;
void Generate(){//1 2 2 3 3
    l=new node();
    l->next=new node(1);
    List tmp=l->next;

    tmp->next=new node(2);tmp=tmp->next;
    tmp->next=new node(2);tmp=tmp->next;
    tmp->next=new node(3);tmp=tmp->next;
    tmp->next=new node(3);tmp=tmp->next;
}

void show(List l){
    if(!l) return;
    node*tmp=l->next;
    while(tmp) {coutnext;}
    cout<

6.假设二叉树以二叉链表存储,设计一个算法判断一颗二叉树是否为完全二叉树?
#include
#include
#include
using namespace std;
struct Node{	//二叉树结点
	int data;
	struct Node* lchild,*rchild;
};
typedef Node* Tree;

bool IsCompleteBinaryTree(Tree t){
    if(!t) return true;
    Tree tmp;
    queue q;  //用于广度优先遍历
    map m;//记录对应结点的编号,从1起
    map m2;//记录当前结点的父节点
    pair lastNodePair;//记录最后一个节点的信息
    int i=0;
    q.push(t);
    while(!q.empty()){
        tmp=q.front();q.pop();
        if(!tmp) continue;
        m[tmp]=++i;
        lastNodePair.first=tmp,lastNodePair.second=i;
        q.push(tmp->lchild);q.push(tmp->rchild);
        m2[tmp->lchild]=tmp,  m2[tmp->rchild]=tmp;
    }
    int lastNumber=lastNodePair.second;
    Node* lastNode=lastNodePair.first;
    Node* parentNode=m2[lastNode];
    int parentNumber=m[parentNode];
    if(parentNumber*2==lastNumber||parentNumber*2+1==lastNumber)//完全二叉树的性质
        return true;
    else return false;
}

7.写算法,对无头结点的单链表中的元素逆置(不允许申请新的节点空间)。

头插法。
#include
#include
using namespace std;
typedef struct node
{
    int data;
    struct node* next;
    node()
    {
        next=NULL;
    }
    node(int x)
    {
        next=NULL;
        data=x;
    }
}*List;
void InverseElements(List l)
{
    if(!l||!l->next) return ;
    List tmp=l->next;
    List tmp2=tmp->next;
    tmp->next=NULL;
    while(tmp2){
        l->next=tmp2;
        tmp2=tmp2->next;
        l->next->next=tmp;
        tmp=l->next;
    }
}
//以上为卷面作答内容   下面为自己验证用
List l=NULL;
void Generate() //1 2 2 3 3
{
    l=new node();
    l->next=new node(1);
    List tmp=l->next;

    tmp->next=new node(2);
    tmp=tmp->next;
    tmp->next=new node(2);
    tmp=tmp->next;
    tmp->next=new node(3);
    tmp=tmp->next;
    tmp->next=new node(3);
    tmp=tmp->next;
}

void show(List l)
{
    if(!l) return;
    node*tmp=l->next;
    while(tmp)
    {
        coutnext;
    }
    cout<

8.将普通链表中值最小的结点提到最前,要求不能申请新的节点。

//PutTheMinToTheFirst
#include
using namespace std;
typedef struct node
{
    int data;
    struct node* next;
    node()
    {
        next=NULL;
    }
    node(int x)
    {
        next=NULL;
        data=x;
    }
}*List;
void PutTheMinToTheFirst(node* head){
    List p,pPrevious,pMin,pMinPrevious;
    pMinPrevious=head;
    pMin=pMinPrevious->next;
    pPrevious=pMinPrevious;
    p=pMin;
    while(p){
        if(p->datadata){
            pMinPrevious=pPrevious;
            pMin=p;
        }
        pPrevious=p;
        p=p->next;
    }
    if(pMin==head->next) return;
    pMinPrevious->next=pMin->next;
    pMin->next=head->next;
    head->next=pMin;
}
////////////以上为卷面作答内容   下面为自己验证用
List l=NULL;
void Generate() //3 2 2 1 3
{
    l=new node();
    l->next=new node(3);
    List tmp=l->next;

    tmp->next=new node(2);
    tmp=tmp->next;
    tmp->next=new node(2);
    tmp=tmp->next;
    tmp->next=new node(1);
    tmp=tmp->next;
    tmp->next=new node(3);
    tmp=tmp->next;
}

void show(List l)
{
    if(!l) return;
    node*tmp=l->next;
    while(tmp)
    {
        coutnext;
    }
    cout<

9.试写出一个递归函数,判断两棵树是否相等。

#include
using namespace std;
struct Node{	//二叉树结点
	int data;
	struct Node* lchild,*rchild;
};
typedef Node* Tree;
bool IsTwoTreesEqual(Tree t1,Tree t2){
	if(!t1 && !t2) 
		return true;	
	if(IsTwoTreesEqual(t1->lchild,t2->lchild) && IsTwoTreesEqual(t1->rchild,t2->rchild)){
		if(t1->data==t2->data)
			return true;
	}
	return false;
}

你可能感兴趣的:(准备工作-笔面试)