數據結構實驗題目

1、已知單鏈表L(帶頭節點)是一個遞增有序表,試編寫一算法,刪除表中值大於min且小於max的節點(若表中有這樣的節點),同時釋放被刪節點的空間,這裏min和max是兩個給定參數。請分析算法時間複雜度。

#include<iostream>
#include<cstdlib>
using namespace std;
typedef struct LNode{
	int a;
	LNode *next;
};
LNode *init_List(int n){              //初始化鏈表 
	LNode *L;
    L=(LNode *)malloc(sizeof(LNode));
    L->next=NULL;
	LNode *p;
	LNode *r = L; 
	if(n!=0){
		int x;
	    while(n--){
		    scanf("%d",&x);
	    	p=(LNode *)malloc(sizeof(LNode));
	    	p->a = x;
	    	p->next = NULL; 
	    	r->next = p;              //使用尾插法 
	    	r = p;
		}	
	}
	return L;	
}
void print_List(LNode *L){            //輸出鏈表內容 
	LNode *p=L->next;
	if(L->next==NULL){
		printf("-1\n");
		return;
	}
    while(p->next != NULL){
		printf("%d ",p->a); p = p->next;
	}
	printf("%d\n",p->a);
} 

LNode *delete2(LNode *L,int min,int max){       //刪除指定區域內的節點 
	LNode* p=L->next,*q=L,*r;
	if(L->next==NULL){
		return L;
	}
	while(p!=NULL){
		if(p->a > min && p->a < max){
			r=p;
			q->next=p->next;
			p=q->next;
        	free(r);                           //釋放被刪除節點的空間 
		}
		else{
			p=p->next;
		    q=q->next;
		}	
	}
	return L;
}
int main(){
	int T,len,q,type,min,max;
	LNode * L;
	scanf("%d",&T);
	while(T--){
		scanf("%d",&len);
		L=init_List(len);
		scanf("%d",&q);
		    while(q--){
		    	scanf("%d",&type);
		    	if(type==1){
		    		print_List(L);
				}
				else if(type==2){
					scanf("%d%d",&min,&max);
					L=delete2(L,min,max);
				}
			}	
	}
	return 0;
}

2、約瑟夫環問題

1)問題描述:有編號爲1, 2…n 的 n 個人按順時針方向圍坐一圈,每人持有一個正整數密碼。開始給定一個正整數 m,從第一個人按順時針方向自1開始報數,報到m者出列,不再參加報數,這時將出列者的密碼作爲m,從出列者順時針方向的下一人開始重新自1開始報數。如此下去,直到所有人都出列。試設計算法,輸出出列者的序列。

2)實驗要求:採用順序和鏈式兩種存儲結構實現

#include<iostream>
#include<cstdlib>
using namespace std;
typedef struct Node{
	int m;                  //m記錄密碼 
	int num;                //記錄初始的位置 
	Node *next;             //下一個節點 
}; 
int count;
Node* init_List(int n){
	int num=1;
	Node* L,*r,*p;
	int m;
	L = (Node*)malloc(sizeof(Node));
	L->next = NULL;
	r=L;                   //尾插法 
	if(n==0) return L;
	else{
		count=0;
		while(n--){
			p = (Node*)malloc(sizeof(Node));
			scanf("%d",&m);
			count++;       //記錄節點數 
			p->m = m;
			p->num = num++; 
			p->next = NULL;
			r->next = p;
			r = p;
		}
	}
	r->next = L->next;  
	return L;
}
void xunhuan_List(Node* L,int m){
	Node *p=L->next,*r=L,*q1;
	int m1=m;
	while(count != 1 ){          //原表中剩一節點則結束 
		m1-=1;                   //第一次從本身開始
	    while(m1--){
		    r=r->next;
		    p=p->next;
	    }
	    printf("%d ",p->num); 	    
	    count--; 
	    if(p->m!=0) m1=p->m;
	    else m1=m;
	    r->next = p->next;       //改變原來的鏈接關係 
	    p = r->next;
	}
	printf("%d\n",p->num);
}

int main(){
	int a,n,m;
	scanf("%d",&a);
	while(a--){
		Node *L;
	    scanf("%d",&n);	
		L = init_List(n);
		scanf("%d",&m);             //初始密碼 
		xunhuan_List(L,m);          //循環 
	} 
	return 0;
}

3.一元稀疏多項式簡單的計算器

1)問題描述:用線性表表示一元稀疏多項式,設計一個一元多項式運算器。

2)實驗要求: 採用單鏈表存儲結構一元稀疏多項式,輸入並建立多項式,輸出多項式,實現多項式加、減運算。

 

#include<iostream>           //多項式問題 
#include<cstdlib>
using namespace std;
typedef struct Node{
	int x;
	int y;
	Node* next;
}; 
Node* init_List(int n){
	Node *L,*p,*r;
	int x,y;
	L=(Node*)malloc(sizeof(Node));
	L->next = NULL;
	r=L;
	if(n==0){                 //使用尾插法 
		return L;
	}
	else{
		while(n--){
			scanf("%d%d",&x,&y);
			p=(Node*)malloc(sizeof(Node));
			p->x=x;
			p->y=y;
			p->next = NULL;
			r->next = p;
			r=p;
		}
	}
	return L;
}
void print_List(Node *L){            //輸出鏈表內容 
	Node *p=L->next;
	if(L->next==NULL){
		printf("-1\n");
		return;
	}
	if(p->x>0){
		printf("%dX^%d",p->x,p->y);
		p=p->next; 
	}
	if(p==NULL){
		printf("\n");
		return;
	}
	else{
	    while(p->next != NULL){
    	if(p->x>0){
    		printf("+%dX^%d",p->x,p->y); 
		    p = p->next;
		}
		else if(p->x<0){
			printf("%dX^%d",p->x,p->y); 
		    p = p->next;
		}
		else if(p->x == 0){
			printf("");
			p=p->next;
		}
	}
	if(p->x>0){
		printf("+%dX^%d\n",p->x,p->y); 
	}
	else if(p->x<0){
		printf("%dX^%d\n",p->x,p->y); 
	}
	else if(p->x == 0){
		printf("\n");
	}	 
	}
 
} 
Node* jian_List(Node* L1,Node* L2){
	Node *p1=L1,*p2=L2->next,*r;
	int flag;
	while(p2!=NULL){
		p1=L1->next;
		flag=0;
	    while(p1!=NULL){
	    	if(p1->y==p2->y){
	    		flag=1;
	    		p1->x =p1->x - p2->x;
			}
			p1=p1->next;
		}
		if(flag==0 && p1==NULL){
			Node* p;
			r=L1->next;
			while(r->next!=NULL) r=r->next;
			p=(Node*)malloc(sizeof(Node));
			p->x = -(p2->x);
			p->y = p2->y; 
			p->next = NULL;
			r->next = p;
			r=p;	
		}
		p2=p2->next;
	} 
	return L1;
}
Node* add_List(Node* L1,Node* L2){
	Node *p1=L1,*p2=L2->next,*r;
	int flag;
	while(p2!=NULL){
		p1=L1->next;
		flag=0;
	    while(p1!=NULL){
	    	if(p1->y == p2->y){
	    		flag=1;
	    		p1->x = p1->x + p2->x;
			}
			p1=p1->next;
		}
		if(flag==0 && p1==NULL){
			Node* p;
			r=L1->next;
			while(r->next!=NULL) r=r->next;
			p=(Node*)malloc(sizeof(Node));
			p->x = p2->x;
			p->y = p2->y; 
			p->next = NULL;
			r->next = p;
			r=p;	
		}
		p2=p2->next;
	}
	return L1;
}
int main(){
	int T,m,n,p,type;
	scanf("%d",&T);
	while(T--){
		Node *L1,*L2,*L21,*L22;
	    scanf("%d%d",&m,&n);
		L1=init_List(m);             //初始化多項式1 
		L2=init_List(n);             //初始化多項式2 
		scanf("%d",&p);
		while(p--){
			scanf("%d",&type);
			if(type==1){
				print_List(L1);
				print_List(L2);
			}
			else if(type==2){        //加運算 
				L1 = add_List(L1,L2);
			}
			else if(type==3){        //減運算 
				L1 = jian_List(L1,L2);
			}
		}	
	}
	return 0;
}

4.十進制數到N進制數的轉換

1)問題描述:將從鍵盤輸入的十進制數轉換爲N(如二進制、八進制、十六進制)進制數據。

2)實驗要求: 利用順序棧實現數制轉換問題

3) 實現提示:

  • 轉換方法利用輾轉相除法;
  • 所轉換的N進制數按低位到高位的順序產生,而通常的輸出是從高位到低位的,恰好與計算過程相反,因此轉換過程中每得到一位N進制數則進棧保存,轉換完畢後依次出棧則正好是轉換結果。

4)注意問題:

  • 何時入棧、出棧

       算法結束條件

#include<iostream>
using namespace std;
#include<cstdlib>
#include<cstring>
#define Max_Size 100
typedef struct SeqStack {
	char data[Max_Size];
	int top;
};
SeqStack *initStack() {        //初始化棧 
	SeqStack *s;
	s = (SeqStack *)malloc(sizeof(SeqStack));
	if (s != NULL)
		s->top = -1;
	return s;
}

void Push(SeqStack *s, int x) {  //入棧 
	if (s->top == Max_Size) {
		return;
	}
	else {
		s->top++;
		s->data[s->top] = x;
	}
	return;
}

int Pop(SeqStack *s) {          //出棧 
	char temp;
	if (s->top == -1) {
		return 0;
	}
	else {
		temp = s->data[s->top];
		s->top--;
	}
	printf("%c",temp);
}
int main(){
	SeqStack *s;
	s = initStack();           //2<=n<=36 
    int x,n;
    scanf("%d%d",&x,&n);
    int count=0;
    if(x == 0){ 
    	Push(s,0);
    }
    int r;
    while(x != 0){            //中間利用輾轉相除法 
        r = x % n; 
        if(r >= 10 && r<=35){ //大於10就轉化爲相應的字母 
            Push(s,r+55);     //根據ASCALL碼轉換
		}
        else{                 //小於10就轉化爲相應數字 
            Push(s,r+'0');
        }
        count++;
        x /= n;
    }
    while(s->top != -1) {  //循環依次輸出棧中的內容 
        Pop(s);	
	}
    return 0;
}

5.判斷“迴文”問題

1)問題描述:所謂迴文,是指從前向後順讀和從後向前倒讀都一樣的字符串。

例如,did;  pop;  I was able 與 elba saw I 等等。

2)實驗要求:編寫程序,利用棧結構判斷一個字符串是否是“迴文”。

3)實現提示:

從左向右遇到的字符,若和棧頂元素比較,若不相等,字符入棧,若相等,出棧。如此繼續,若棧空,字符串是“迴文”,否則不是。

#include<iostream>
#include<cstring>
#include<cstdlib>
using namespace std; 
typedef struct Node{          //棧 
	int data[200];
	int top;
};
Node *init_List(){           //建立棧 
	Node *L;
	L = (Node*)malloc(sizeof(Node));
	L->top=-1;
	return L;
} 

Node* push(Node* L,char x){   //入棧 
	L->top++;
	L->data[L->top] = x; 
	return L;
} 

Node* pop(Node* L){         //出棧 
	L->top--;
	return L;
}

int main(){
	char a[200],b;
	int i=0;
    Node* L;
	L = init_List();
	int n=0; 
	
	while((b=getchar()) && b!='\n'){
		a[i++] = b;
		n++;
	} 
	
	if(n%2==1){
		for(i=(n-1)/2;a[i]!='\0';i++){    //中間數字之後的前移 
			a[i] = a[i+1];
		}
		n=n-1;
	}                                     //end 全部變成偶數個字符 
	
	for(i=0;i<n/2;i++){                  //前n/2個入棧 
		L = push(L,a[i]);
	}                                
	
	for(i=n/2;L->top!=-1;i++){           //從第n/2個開始逐個與棧內的元素對比 
		if(a[i] != L->data[L->top]){
			printf("NO"); 
			break;
		}
		L = pop(L);
	}
	if(L->top == -1){
		printf("YES");
	} 
	return 0;
}

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章