考研算法真題


一些算法真題選集,僅供參考,暫停更,開始手撕。


1. 統計出單鏈表HL中結點的值等於給定值X的結點數

int CountX(LNode *HL, ElementType X){
	LNode *p;
	int count = 0;
	if(HL == NULL)	return 0;
	p = HL->next;
	while(p != NULL){
		if(p->data == X)
		++count;
		p = p->next;
	}
	return count;
} 

2.設有一組初始記錄關鍵字序列(K1,K2,… Kn),要求設計一個算法能夠在 O(n) 的時間復雜度內將線性表划分成兩部分,其中左半部分的每個關鍵字均小於 Ki ,右半部分的每個關鍵字均大於等於 Ki

void quickpass(int r[], int s,int t)
{
	int i=s, j=t, x=r[s];
	while(i<j){	
		while (i<j &&r[j]>x) j=j-1; if (i<j) {r[i]=r[j];i=i+1;}
		while (i<j && r[i]<x) i=i+1;if (i<j) {r[j]=r[i];j=j-1;}
	}
	r[i]=x;
}

3. 設有兩個集合A和集合B,要求設計生成集合C=A∩B的算法,其中集合A、B和C用鏈式存儲結構表示

typedef struct node 
{	int data;
 	struct node *next;
}lklist;
void intersection(lklist*ha,lklist *hb,lklist *&hc)
{
	lklist *p,*q,*t;
	for(p=ha,hc=0;p!=0;p=p->next)
	{ 
		for(q=hb;q!=0;q=q->next) 
		{
			if (q->data==p->data) break;
		}
		if(q!=0)
		{
			t=(lklist*)malloc(sizeof(lklist)); 
			t->data=p->data;t->next=hc; hc=t;
		}
	}
}

4. 設計在單鏈表中刪除值相同的多余結點的算法

typedef int datatype;
typedef struct node
{
    datatype data;
    struct node *front, *next;
}lklist;
void delredundant(lklist *&head)
{
	lklist *p,*q,*s;
	for(p=head; p!=0; p=p->next)
	{
		for(q=p->next, s=q; q!=0;)
		{
			if(q->data==p->data)
			{
				s->next=q->next; free(q); q=s->next;
			}else{
				s=q; q=q->next;
			}
		}
	}
}	

5. 設計一個求結點 x 在二叉樹中的雙親結點算法

typedef struct node 
{	datatype data;
 	struct node *lchild,*rchild;
} bitree;
bitree *q[20]; int r=0,f=0,flag=0;
void preorder(bitree *bt, char x)
{
	if (bt!=0 && flag==0)
		if (bt->data==x) { flag=1; return;}
		else {
			r=(r+1)% 20; q[r]=bt; 
			preorder(bt->lchild,x); 
			preorder(bt->rchild,x); 
		}
}
void parent(bitree *bt,char x)
{
	int i;
	preorder(bt,x);
	for(i=f+1; i<=r; i++) 
	{
		if (q[i]->lchild->data==x || q[i]->rchild->data) break;
	}
	if (flag==0) printf("not found x\n");
	else if (i<=r) printf("%c",bt->data); 
	else printf("not parent");
}

6. 設單鏈表中有僅三類字符的數據元素(大寫字母、數字和其它字符),要求利用原單鏈表中結點空間設計出三個單鏈表的算法,使每個單鏈表只包含同類字符

typedef char datatype;
typedef struct node 
{	datatype data;
 	struct node *next;
}lklist;
void split(lklist *head,lklist*&ha,lklist *&hb,lklist *&hc)
{
	lklist *p; ha=0,hb=0,hc=0;
	for(p=head;p!=0;p=head)
	{
		 head=p->next; p->next=0;
		 if (p->data>='A' && p->data<='Z') {p->next=ha;ha=p;}
		 else if (p->data>='0' && p->data<='9')
		 {p->next=hb; hb=p;} else {p->next=hc; hc=p;}
  	}
}

7. 設計在鏈式存儲結構上交換二叉樹中所有結點左右子樹的算法

typedef struct node
{	int data;
 	struct node *lchild,*rchild;
}Bitree;
void swapbitree(Bitree *bt)
{
	Bitree *p;
	if(bt==0)
	{
		return;
	}
	swapbitree(bt->lchild);
	swapbitree(bt->rchild);
	p=bt->lchild;
	bt->lchild=bt->rchild;
	bt->rchild=p;
}

8. 在鏈式存儲結構上建立一顆二叉排序樹

#define n10
typedef struct node
{	int key;
 	struct node *lchild,*rchild;
}bitree;
void bstinsert(bitree *&bt,int key)
{
	if (bt==0)
	{
		bt=(bitree*)malloc(sizeof(bitree)); 
		bt->key=key;bt->lchild=bt->rchild=0;
	}
	else if (bt->key>key) 
		bstinsert(bt->lchild,key);
	else bstinsert(bt->rchild,key);
}
void createbsttree(bitree *&bt)
{
	int i;
	for(i=1;i<=n;i++)bstinsert(bt,random(100));
}

9. 設計判斷兩個二叉樹是否相同的算法

typedef struct node
{	datatype data;
 	struct node *lchild, *rchild;
}bitree; //二叉鏈表存儲結構
int judgebitree(bitree *bt1,bitree *bt2)//判斷兩個二叉樹是否相同。
{
  	if (bt1==0 && bt2==0)//兩棵樹對應位置都為空返回1
  		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);
}

10. 設計兩個有序單鏈表的合並排序算法

Typedef struct Lnode{
	Datatype data;
	Struct Lnode *next;
}Lnode,*linklist;
void Merge_List(Linklist &la,linklist &b){
	LNode *pa=la->next,*pb=lb->next,*r;   //r指針防止斷鏈
	la->next=null;                    
		while(pa&&pb){
		if(pa->data >= pb->data){
			r=pa->next;                   
			pa->next=la->next;
			la->next=pa;
			pa=r;                  //pa重新指向未排序位置
		}
		if(pa->data <= pb->data){
			r=pb->next;                  
			pb->next=la->next;
			la->next=pb;
			pb=r;                  
		}
	}
	if(pa)  pb=pa;           
	while(pb){               
		r=pb->next;
		pb->next=la->next;
		la->next=pb;
		pb=r;
	}
	free(lb);                //釋放掉lb的空閑空間
}

11. 設計在順序有序表中實現二分(折半)查找的算法

struct record
{	int key;
 	int others;
};
int bisearch(struct record r[], int k)
{
	int low=0, mid, high=n-1;
	while(low<=high)
	{
		mid=(low+high)/2;
		if(r[mid].key==k)
		{
			return (mid+1);
		}
		else if(r[mid].key>k)
		{
			high=mid-1;
		}else{
			low=mid+1;
		}
	}
	return 0;
}

12. 設計判斷二叉樹是否為二叉排序樹的算法

//遞歸方式
KeyType predt=-32767;
int JudgeBST(BisTree bt)
{
	int b1, b2;
	if(bt==NULL)
	{
		return 1;
	}else{
		b1=JudgeBST(bt->lchild); //遞歸
		if(b1==0 || predt>=bt->data)
			return 0;
		predt=bt->data;
		b2=JudgeBST(bt->rchild);
		return b2;	
	}
}
//非遞歸方式
int InOrderTraverse(BiTree T)
{
	BiTree p;
	p=T;
	while(p||!StackEmpty(S))
	{
		if(p)
		{
			Push(S,p);
			if(p->data>p->lchild->data)
				p=p->lchild;
			else return 0;
		}
		else
		{
			Pop(S,p);
			cout<<p->data<<" ";
			if(p->data<p->rchild->data)
				p=p->rchild;
			else return 0;
		}
	}
	return 1;
}

13. 在鏈式存儲結構上設計直接插入排序

void straightinsertsort(lklist *&head)
{
	lklist *s,*p,*q;
	int t;
	if(head==0 || head->next==0) return ;
	else for(q=head, p=head->next; p!=0; p=q->next)
	{
		for(s=head; s!=q->next; s=s->next)
		{
			if(s->data > p->data) break;
			if(s==q->next) q=p;
			else{
				q->next=p->next;
				p->next=s->next;
				s->next=p;
				t=p->data;
				p->data=s->data;
				s->data=t;
			}
		}	
	}
}

14. 設計在鏈式結構上實現簡單選擇排序

typedef struct LNode
{	int data;
 	struct LNode *next
}*Linklist;
void  simpleselectSort(Linklist *&head)
{
	Linklist *p,*q,*s;
	int min,t;
	if(head==0 || head->next==0)
	{
		return;
	}
	for(q=head;q!=0;q=q->next)
	{
		min=q->data;
		s=q;
		for(p=q->next;p!=0;p=p->next)
		{
			if(min>p->data)
			{
				min=p->data;
				s=p;
			}
		}
		if(s!=q)
		{
			t=s->data;
			s->data=q->data;
			q->data=t;
		}
	}
}

15.設計求結點在二叉排序樹中層次的算法

int lev=0;
typedef struct node
{
	int key;
	struct node *lchild,*rchild;
}bitree;
void level(bitree *bt, int x)
{
	if(bt!=0)
	{
		lev++;
		if(bt->key==x)
		{
			return;
		}
		else if(bt->key>x)
		{
			level(bt->lchild, x);
		}
	}
	else{
		level(bt->rchild, x);
	}
}

16. 設計一個在鏈式存儲結構上統計二叉樹中結點個數的算法

void countnode(bitree *bt,int &count)
{
	if(bt!=0)
	{
		count++;
		countnode(bt->lchild,count); 
		countnode(bt->rchild,count);
	}
}

17. 設計一個算法將無向圖的鄰接矩陣轉為對應鄰接表的算法

typedef struct 
{	int vertex[m];
 	int edge[m][m];
}gadjmatrix;

typedef structnode1
{	int info;
 	int adjvertex;
 	struct node1 *nextarc;
}glinklistnode;

typedef structnode2
{	int vertexinfo;
 	glinklistnode *firstarc;
}glinkheadnode;

void adjmatrixtoadjlist(gadjmatrix g1[ ],glinkheadnode g2[ ])
{
	int i,j;glinklistnode *p;
	for(i=0;i<=n-1;i++)g2[i].firstarc=0;
	for(i=0;i<=n-1;i++)for(j=0;j<=n-1;j++)
	if(g1.edge[i][j]==1)
	{
		p=(glinklistnode*)malloc(sizeof(glinklistnode)); p->adjvertex=j;
		p->nextarc=g[i].firstarc; g[i].firstarc=p;
		p=(glinklistnode*)malloc(sizeof(glinklistnode)); p->adjvertex=i;
		p->nextarc=g[j].firstarc; g[j].firstarc=p;
	}
}

18. 設計計算二叉樹中所有結點值之和的算法

void sum(bitree *bt,int &s)
{
   if(bt!=0)
   {
		s=s+bt->data; 
		sum(bt->lchild,s);
		sum(bt->rchild,s);
	}   
}

19. 設計將所有奇數移到所有偶數之前的算法

void quickpass(int r[], int s, int t)
{
	int i=s,j=t,x=r[s];
	while(i<j)
	{
		while (i<j && r[j]%2==0)
			j=j-1;  
			if (i<j) {r[i]=r[j];i=i+1;}
		while (i<j && r[i]%2==1)
			i=i+1; 
			if (i<j) {r[j]=r[i];j=j-1;}
	}
	r[i]=x;
}

20. 設計判斷單鏈表中元素是否是遞增的算法

int isriselk(lklist *head)
{
	if(head==0||head->next==0)return(1);
	else
		for(q=head,p=head->next;p!=0; q=p,p=p->next)
			if(q->data>p->data) return(0);
	return(1);
}

21. 設計在鏈式存儲結構上合並排序的算法

void mergelklist(lklist *ha,lklist *hb,lklist *&hc)
{
	lklist *s=hc=0;
	while(ha!=0 && hb!=0)
		if(ha->data<hb->data)
		{
			if(s==0) hc=s=ha; 
			else {s->next=ha; s=ha;};
			ha=ha->next;
		}
		else {
			if(s==0) hc=s=hb; 
			else {s->next=hb; s=hb;};
			hb=hb->next;
		}
		if(ha==0) s->next=hb; 
		else s->next=ha;
}

22. 設計在二叉排序樹上查找結點X的算法

bitree *bstsearch1(bitree *t, int key)
{
	bitree *p=t;
	while(p!=0) 
		if (p->key==key)return(p);
		else if (p->key>key) p=p->lchild; 
		else p=p->rchild;
	return(0);
}

23. 設關鍵字序列(k1,k2,…,kn-1)是堆,設計算法將關鍵字序列(k1,k2,…,kn-1,x)調整為堆

void adjustheap(int r[ ],int n)
{
	int j=n,i=j/2,temp=r[j-1];
	while (i>=1) 
		if(temp>=r[i-1])break; 
		else{
			r[j-1]=r[i-1]; j=i; i=i/2;
		}
	r[j-1]=temp;
}

24.已知深度為h的二叉樹以一維數組BT(1:2h-1)作為其存儲結構。請寫一個算法,求該二叉樹中葉子結點的個數

int leaves(int h) //求深度為h以順序結構存儲的二叉樹的葉子結點
{
    int BT[]; int len=2^h-1,count=0;
    for(int i=1;i<=len;i++)
    {
        if(BT[i]!=0) //假定二叉樹結點值是整數,“虛結點”用0補充
        {
            if((i*2)>len) count++; //第i個結點沒有子女肯定是葉子結點
            else if(BT[2*i]==0&&2*i+1<=len&&BT[2*i+1]==0) count++; //無左右子女結點為葉子
        }
    }
    return count;
}

25、建立二叉樹

typedef struct node
{
    int data;
    struct node *lchild;
    struct ndoe *rchild;
}btree;
void createbitree(bitree *&bt)
{
    scanf("%c",&ch);
    if(ch=='#')
        bt=0;
    else
    {
        bt=(bitree*)malloc(sizeof(bitree));
        bt->data=ch;
        createbitree(bt->lchild);
        createbitree(bt->rchild);
    }
}

26、利用尾部插入的方法建立單鏈表

typedef struct node
{
	int data;
    struct node *next;
}lklist;
void lklistcreate(lklist *&head)
{
    for(i=1;i<=n;i++)
    {
        p=(lklist*)malloc(sizeof(lklist));scanf("%d",&(p->data));p->next=0;
        if(i==1) head=q=p; else{q->next=p;q=p;}
    }
}

27、n個元素采用順序存儲,設計直接插入排序算法

void insertsort()
{	
    //a為順序存儲所需數組,n為元素個數
    for(int i=1;i<n;i++)
    {
        int key=a[i];
        int j=i-1;
        while(j>=0&&a[j]>key)
        {
            a[j+1]=a[j];
            j--;
        }
        a[j+1]=key;
    }
}

28、對含有n個互不相同元素的線性表,設計一個算法同時找最大元素和最小元素

void getMaxandMin(int A[],int n,int &max,int &min) //O(n)
{
    int i;
    max=min=A[0];
    for(i=0;i<n;i++)
    {
        if(A[i]>max) max=A[i];
        if(A[i]<min) min=A[i];
    }
}

29、編寫一個算法,完成對n叉樹各節點的層次遍歷

// 定義n叉樹的節點結構體
typedef struct node_t
{
    char* name;               // 節點名
    int   n_children;         // 子節點個數
    int   level;              // 記錄該節點在多叉樹中的層數
    struct node_t** children; // 指向其自身的子節點,children一個數組,該數組中的元素時node_t*指針
} NODE; // 對結構體重命名

// 將多叉樹中的節點,按照深度進行輸出,實質上實現的是層次優先遍歷
void levelOrder(NODE* head)
{
    NODE* p = NULL;
    QUEUE* q = NULL; // 定義一個隊列
    STACK* s = NULL; // 定義一個棧
    int i = 0;

    q = QUEUEinit(100); // 將隊列初始化大小為100
    s = STACKinit(100); // 將棧初始化大小為100

    head->level = 0; // 根節點的深度為0
    
    // 將根節點入隊列
    QUEUEenqueue(q, head);

    // 對多叉樹中的節點的深度值level進行賦值
    // 采用層次優先遍歷方法,借助於隊列
    while (QUEUEempty(q) == 0) // 如果隊列q不為空
    {
        QUEUEdequeue(q, &p); // 出隊列
        for (i = 0; i < p->n_children; ++i)
        {
            p->children[i]->level = p->level + 1; // 對子節點深度進行賦值:父節點深度加1
            QUEUEenqueue(q, p->children[i]);      // 將子節點入隊列
        }
        STACKpush(s, p); // 將p入棧
    }

    while (STACKempty(s) == 0) // 不為空
    {
        STACKpop(s, &p); // 彈棧
        fprintf(stdout, "   %d %s\n", p->level, p->name);
    }

    QUEUEdestroy(q); // 消毀隊列
    STACKdestroy(s); // 消毀棧
}

29、設 h 是帶表頭結點的單鏈表的頭指針,請設計一個逆置這個單鏈表的程序。

typedef struct node
{
    int data;
    struct node *link
}LNode;
void invert(LNode *h)
{
    LNode *s,*p;
    p=h->link;  //p指針用於記錄當前訪問節點
    h->link=NULL; //h置為NULL是為了重新建立一個逆序鏈表而准備的頭節點
    while(p!=NULL)
    {
        s=p; //s用於記錄當前訪問的節點
        p=p->link; //p用於指向后面斷開鏈表的第一個節點
        s->link=h->link; //將s指向的節點插入到頭節點后面
        h->link=s; //將頭節點指針指向第一個節點s
    }
}

30、以二叉鏈表為二叉樹的存儲結構,寫一算法計算葉子結點個數

typedef struct BiTNode
{
    TDataType data;
    struct BiTNode *lchild,*rchild;
}BiTree;
void countLeaf(BiTNode *t,int &count)
{
    if(t!=NULL)  //不空的情況下
    {
        if(t->lchild==NULL && t-rchild==NULL)
        {
            count++;
            countLeaf(t->lchild);
            countLeaf(t->rchild);
        }
    }
}

31、設有一個帶頭結點的單鏈表h,數據項遞減有序。寫一算法,重新排列鏈表,使數據項遞增有序,要求時間復雜度O(n)

//本質上是將單鏈表逆置,不同的問法罷了
typedef struct node
{
    int data;
    struct node *link
}LNode;
void invert(LNode *h)
{
    LNode *s,*p;
    p=h->link;  //p指針用於記錄當前訪問節點
    h->link=NULL; //h置為NULL是為了重新建立一個逆序鏈表而准備的頭節點
    while(p!=NULL)
    {
        s=p; //s用於記錄當前訪問的節點
        p=p->link; //p用於指向后面斷開鏈表的第一個節點
        s->link=h->link; //將s指向的節點插入到頭節點后面
        h->link=s; //將頭節點指針指向第一個節點s
    }
}

32、設計二叉樹先序、中序、后序遍歷的遞歸算法

//先序
void preOrder(BTNode *b)
{
    if(b!=NULL)
    {
        printf("%c",b->data);
        preOrder(b->lchild);
        preOrder(b->rchild);
    }
}
//中序
void inOrder(BTNode *b)
{
    if(b!=NULL)
    {
        inOrder(b->lchild);
        printf("%c",b->data);
        inOrder(b->rchild);
    }
}
//后序
void postOrder(BTNode *b)
{
    if(b!=NULL)
    {
        postOrder(b->lchild);
        postOrder(b->rchild);
        printf("%c",b->data);
    }
}

33、設計二叉樹先序、中序、后序遍歷的非遞歸算法

//先序
void preOrder(BTNode *b)
{
    BTNode *p;
    SqStack *st; //定義棧指針st
    InitStack(st); //初始化棧
    if(b!=NULL)
    {
        Push(st,b); //根節點進棧
        while(!StackEmpty(st)) //棧不為空時循環
        {
            Pop(st,p); //退棧結點p並訪問
            printf("%c",p->data);
            if(p->rchild!=NULL) //有右孩子進棧
                Push(st,p->rchild);
            if(p->lchild!=NULL) //有左孩子進棧
                Push(st,p->lchild);
        }
        printf("\n");
    }
    DestroyStack(st);
}
//中序
void inOrder(BTNode *b)
{
    BTNode *p;
    SqStack *st;
    InitStack(st);
    p=b;
    while(!SatckEmpty(st)||p!=NULL)
    {
        while(p!=NULL) //掃描結點p的所有左下結點並進棧
        {
            Push(st,p); //結點p進棧
            p=p->lchild; //移動到左孩子
        }
        if(!StackEmpty(st))
        {
            Pop(st,p); //出棧結點p
            printf("%c",p->data); //訪問結點p
            p=p->rchild; //轉向處理其右子樹
        }
    }
    printf("\n");
    DestroyStack(st);
}
//后序
void postOrder(BTNode *b)
{
    BTNode *p,*r;
    bool flag;
    SqStack *st;
    InitStack(st);
    p=b;
    do
    {
        while(p!=NULL) //掃描結點p的所有左下結點並進棧
        {
            Push(st,p); //結點p進棧
            p=p->lchild; //移動到左孩子
        }
        r=NULL; //r指向剛訪問的結點,初始時為空
        flag=true; //flag為真表示正在處理棧頂結點
        while(!StackEmpty(st)&&flag)
        {
            GetTop(st,p); //取出當前棧頂結點p
            if(p->rchild==r) //若結點p的右孩子為空或為剛剛訪問過的結點
            {
                printf("%c",p->data); //訪問結點p
                Pop(st,p); 
                r=p; //r指向剛訪問過的結點
            }
            else
            {
                p=p->rchild; //轉向處理其右子樹
                flag=false; //表示當前不是處理棧頂結點
            }
        }
    }while(!StackEmpty(st)); //棧不空循環
    printf("\n");
    DestroyStack(st);
}

34、設計二叉樹的層序遍歷

void levelOrder(BTNode *b)
{
    BTNode *p;
    SqQuene *qu;
    InitQueue(qu);
    enQuenu(qu,b); //根節點指針進入隊列
    while(!QueueEmpty(qu)) //隊不為空循環
    {
        deQueue(qu,p); //出隊結點p
        printf("%c",p->data); //訪問結點p
        if(p->lchild!=NULL) //有左孩子時將其進隊
            enQueue(qu,p->lchild);
        if(p->rchild!=NULL) //有右孩子時將其進隊
            enQueue(qu,p->rchild);
    }
}

35、線性表的插入和刪除操作

typedef struct LNode
{
    ElemType data;
    struct LNode *next; 
}LNode,*LinkList;
//插入
Status insert(LinkList &L,int i,ElemType e)
{
    p=L; j=0;
    while(p&&j<i-1);
    {
        p=p->next;
        ++j;
    }
    if(!p||j>i-1)
    {
        return ERROR; 
    }
    s=(LinkList)malloc(sizeof(LNode));
    s->data=e;
    s->next=p->next;
    p->next=s;
    return OK;
}
//刪除
Status delete(LinkList &L,int i,ElemType &e)
{
    p=L; j=0;
    while(p->next&&j<i-1)
    {
        p=p->next;
        ++j;
    }
    if(p->next||j>i-1)
        return ERROR;
    q=p->next;
    p->next=q->next;
    e=q->data;
    free(q);
    return OK;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM