數據結構篇——隊列

隊列的定義

是隻允許在一端進行插入操作,而在另一端進行刪除操作的線性表。與棧相反,隊列是 一種先進先出(First In First Out,FIFO)的線性表。

隊列的鏈式存儲結構

#include<stdio.h>
#include<stdlib.h>

typedef int ElemType;
typedef struct Node{
	ElemType data;
	struct Node *next;
}Node,LinkQueue;
Node *R;
void init(LinkQueue *Q){
	Q->data=0;
	Q->next=NULL;
	R=Q;
	for(int i=1;i<=5;i++){
		Node *n=malloc(sizeof(Node));
		n->data=i;
		n->next=R->next;
		R->next=n;
		R=n;
		Q->data++;

	}
}
void show(LinkQueue *Q){
	if(Q->data==0){
		printf(">>>隊列爲空!\n");
		return;
	}
	Node *p=Q;
	printf("[");
	while(1){
		p=p->next;
		if(p=R){
			printf("%d]\n",p->data);
			break;
		}else{
			printf("%d,",p->data);
		}
	}
}
void enqueue(LinkQueue *Q,ElemType e){
	Node *n=malloc(sizeof(Node));
	n->data=e;
	n->next=R-next;
	R->next=n;
	R=n;
	Q->data++;
}
int dequeue(LinkQueue *Q,int *e){
    if(Q->data==0){
    	printf(">>>隊列爲空!\n");
    	return 0;
    }
    Node *n=Q->next;
    Q->next=n->next;
    *e=n->data;
    free(n);
    Q->data--;
    if(Q->data==0){
    	R=Q;
    }
    return 1;
}
void main(){

	LinkQueue Q;  //L S Q T
	int choice;
    ElemType e;
	printf("----------單鏈隊列-----\n");
	print("1.初始化\n");
	printf("2.入隊\n");
	printf("3.出隊\n");
	printf("4.長度\n");
	printf("5.打印\n");
	printf("0.退出\n");
	while(1){
		printf(">>>請選擇:");
		scanf("%d",&choice);
		switch(choice){
			case 1:
			    break;
			case 2:
			    print(">>>請輸入入隊的元素:");
                scanf("%d",&e);
                enqueue(&Q,e);
			    break;
			case 3:
			    if(dequeue(&Q,e)){
			    	printf(">>>出隊元素爲%d",e);
			    }
			    break;
			case 4:
			    printf(">>>長度爲%d\n",Q.data);
			    break;
			case 5:
			    show(&Q);
			    break;
			case 0:
			    break;  
		}

	}
}

循環隊列的定義

循環隊列它的容量是固定的,並且它的隊頭和隊尾指針都可以隨着元素入出隊列而發生 改變,這樣循環隊列邏輯上就好像是一個環形存儲空間,但是要注意的是,在實際的內存當 中,不可能有真的環形存儲區,我們只是用順序表模擬出來的邏輯上的循環。

/*

64個盤子x->z
    先63 x->y 藉助z
        先62 x->z 藉助y
            先61 x->y 藉助z
                ...
            第62 x->z
            後61 y->z 藉助x
                ...
        第63 x->y 
        後62 z->y 藉助x
    第64 x->z
    後63 y->z 藉助x
        先62 y->x 藉助z
            先61 y->z 藉助x
            第62 y->x
            後61 z->x 藉助y
        第62 y->z
        後62 x->z 藉助y
一共num
先移動num-1 x->y 藉助z
    先移動num-2 x->y 藉助z
    再移動num-1 x->z
    後移動num-2 y->z 藉助x
再移動num   x->z
後移動num-1 y->z 藉助x

num=64
void move(num,x,y,z){
    if(num==1){
        x->z
    }else{
        move(num-1,x,z,y)
        num x->z
        move(num-1,y,x,z)
    }
}

 */
#include<stdio.h>
#include<stdlib.h>
typedef int ElemType;
typedef struct Node{
	ElemType data;
	struct Node *next;
}Node,LinkStack;
void init(LinkStack *S,int num){
	S->data=0;
	S->next=NULL;
	for(int i=1;i<=num;i++){
		Node *n=malloc(sizeof(Node));
		n->data=i;
		n->next=R->next;;
		R->next=n;
		R=n;
		S->data++;
	}
}
void show(LinkStack *S){
	if(S->data==0){
		printf("[]\n");
		return;
	}
	printf("[");
	Node *p=S;
	while(1){
		p=p->next;
        if(p->next==NULL){
            printf("%d]\n",p->data);
            break;
        }else{
        	printf("%d,",p->data);
        }
	}
}
void push(LinkStack *L,Node *n){
	// 先找尾指針
	Node *p=S;
	while(1){
		p=p->next;
		if(p->next=NULL){
			break;
		}
		p=p->next;
	}
	n->next=p->next;
	p->next=n;
	S->data++;

}
Node* pop(LinkStack *s){
	Node *p=S;
	while(1){
		p=p->next;
		if(p->next->next==NULL){
			break;

		}
		p=p->next;
	}
	Node *n=p->next;
	p->next=NULL;
	S->data--;
	return;
}
void move(int num,LinkStack *from LinkStack *mid,LinkStack *to){
	if(num==1){
		//printf("%c->%c",from,to);
		push(to,n);
	}else{
		move(num-1,from,to,mid);
		//printf("%c->%c",from,to);
		push(to,pop(from));
		move(num-1,mid,from,to);
	}
}
void main(){
	printf(">>>請輸入盤子個數:");
    scanf("%d",&num);
    move(num,'x','y','z');
    LinkStack L1,L2,L3;
    init(&L1,num);
    init(&L2,0);
    init(&L3,0);
    show(&L1);
    printf("&L1:");
    show(&L2);
    printf("&L2:");
    show(&L3);
    printf("&L3:");
    scanf("%d",&num,&L2,&L3);
    printf("===============\n");
    printf("&L1:");
    show(&L1);
    printf("&L1:");
    show(&L2);
    printf("&L2:");
    show(&L3);
    printf("&L3:");
}

// 八皇后
/*

 */
#include<stdio.h>
#define TRUE 1
#define FALSE 0
typedef int Status;
int count=0;// 統計次數
Status hasAttack(int row,int col,int arr[8][8]){
    //北
    for(int x=row-1;x>=0;x--){
    	if(arr[x][col]==1){
    		return TRUE;
    	}
    }
    //南
    for(int x=row+1;x<8;x++){
    	if(arr[x][col]==1){
    		return TRUE;
    	}
    }
    
    //東
    for(int y=col;y<8;y++){
    	if(arr[row][y]==1){
    		return TRUE;
    	}
    }
    //西
    for(int y=col-1;y>=0;y--){
    	if(arr[row][y]==1){
    		return TRUE;
    	}
    }
    //東北
    for(int x=row-1;y=col+1;x>=0&&y<8;x--,y++){
    	if(arr[row][y]==1){
    		return TRUE;
    	}
    }
    //西北
    for(int x=row-1;y=col-1;x>=0&&y<8;x--,y--){
    	if(arr[row][y]==1){
    		return TRUE;
    	}
    }
    //東南
    for(int x=row+1;y=col+1;x>=8&&y<8;x++,y++){
    	if(arr[row][y]==1){
    		return TRUE;
    	}
    }
    //西南
    for(int x=row+1;y=col-1;x>=8&&y<0;x++,y--){
    	if(arr[row][y]==1){
    		return TRUE;
    	}
    }
    return FALSE;
}
#include<stdlib.h>
void eightQeen(int row,int col,int arr[8][8]){
    /*
    在當前row尋找可能出現的皇后,在此基礎之上進行下一行的尋找
    如果行數到9,說明前8行排布完畢,直接打印或退出即可
     */
    int newArr[8][8];
    for(int i=0;i<8;i++){
    	for(int j=0;j<8;j++){
    		newArr[i][j]=arr[i][j];
    	}
    }
    if(row>7){
        count++;
        printf("%d種:\n");
        for(int i=0;i<8;i++){
        	for(int j=0;j<8;j++){
        		printf("%d ",newArr[i][j]);
        	}
       	printf("\n");
        }
        printf("\n");
    }else{
    	 for(int c=0;c<col;c++){
        	// true 有衝突 false 沒衝突
        	if(!hasAttack(row,c,newArr)){
        		for(int k=0;k<col;k++){
        			newArr[row][k]=0;
        		}
        		newArr[row][c]=1;
        		eightQeen(row+1,8,new333wArr);
        	}
        }
    }
        
    
}

void main(){
    // 先將空二維數組建立
    for(int i=0;i<8;i++){
    	for(int j=0;j<8;j++){
    		a[i][j]=0;
    	}
    }
    eightQeen(0,8,arr);
    printf("一共%d",count);
}

/*
eq(0,8)
    0,0
    eq(1,8)
        1,2
        eq(2,8)
            2,4
            eq(3,8)
                3,1 
                eq(4,8) X
                    4,3
                    eq(5,8) X
                    4,7
                    eq(5,8) X
                3,6
                eq(4,8)
                    4,1X
                    eq(5,8)X
                        5,3X
                        eq(6,8)X
                            6,5X
                            eq(7,8) X
                    4,3
                    eq
                3,7
            2,5
            2,6
            2,7
        1,3
        1,4
        1,5
        1,6
        1,7
    0,1
    0,2
    0,3
    0,4
    0,5
    0,6
    0,7

*/

隊列的順序存儲

#include<stdio.h>
#define MAx_SIZE 10
typedef int ElemType;
typedef struct{
    ElemType datas[MAx_SIZE];
    int front;//頭
    int rear;// 尾
    int Length; // 長度
}SeqQueue;
void init(SeqQueue *Q){
	Q->front=0;
	Q->rear=0;
	Q->length=0;
	for(int i=1;i<=5;i++){
		Q->datas[Q->rear++]=i;
		Q->length++;
	}
}
void show(SeqQueue *Q){
	if(Q->length==0){
		printf("[]\n");
		return;
	}
	printf("[");
	for(int i=Q->front;i!=Q->rear;i=(i+1)%MAx_SIZE){
		if((i+1)%MAx_SIZE==Q->rear){
		    printf("%d]\n",Q->datas[i]);
			break;
		}else{
		printf("%d",Q->datas[i]);
    }
	i=(i+1)%MAx_SIZE;
	}
}
void enqueue(SeqQueue *Q,ElemType e){
	if((Q->rear+1)%MAx_SIZE==Q->front){
		printf(">>>隊列已滿!\n");
		return;
	}
	Q->datas[Q->rear]=e;
	Q->rear=(Q->rear+1)%MAx_SIZE;
	Q->length++;
}
int dequeue(SeqQueue *Q,ElemType e){// Q->front==Q->rear
	if(Q->length==0){
		printf(">>>隊列爲空!\n");
		return 0;
	}
	*e=Q->datas[Q->front];
	Q->front=(Q->front+1)%MAx_SIZE;
	Q->length--;
	return 1;
}
void main(){
	SeqQueue Q;  //L S Q T
	int choice;
    ElemType e;
	printf("----------順序循環隊列-----\n");
	print("1.初始化\n");
	printf("2.入隊\n");
	printf("3.出隊\n");
	printf("4.長度\n");
	printf("5.打印\n");
	printf("0.退出\n");
	while(1){
		printf(">>>請選擇:");
		scanf("%d",&choice);
		switch(choice){
			case 1:
			    break;
			case 2:
			    print(">>>請輸入入隊的元素:");
                scanf("%d",&e);
                enqueue(&Q,e);
			    break;
			case 3:
			    if(dequeue(&Q,e)){
			    	printf(">>>出隊元素爲%d",e);
			    }
			    break;
			case 4:
			    printf(">>>長度爲%d\n",Q.Length);
			    break;
			case 5:
			    show(&Q);
			    break;
			case 0:
			    break;  
		}

	}
}

隊列的鏈式存儲

#include<stdio.h>
#include<stdlib.h>

typedef int ElemType;
typedef struct Node{
	ElemType data;
	struct Node *next;
}Node,LinkQueue;
Node *R;
void init(LinkQueue *Q){
	Q->data=0;
	Q->next=NULL;
	R=Q;
	for(int i=1;i<=5;i++){
		Node *n=malloc(sizeof(Node));
		n->data=i;
		n->next=R->next;
		R->next=n;
		R=n;
		Q->data++;

	}
}
void show(LinkQueue *Q){
	if(Q->data==0){
		printf(">>>隊列爲空!\n");
		return;
	}
	Node *p=Q;
	printf("[");
	while(1){
		p=p->next;
		if(p=R){
			printf("%d]\n",p->data);
			break;
		}else{
			printf("%d,",p->data);
		}
	}
}
void enqueue(LinkQueue *Q,ElemType e){
	Node *n=malloc(sizeof(Node));
	n->data=e;
	n->next=R-next;
	R->next=n;
	R=n;
	Q->data++;
}
int dequeue(LinkQueue *Q,int *e){
    if(Q->data==0){
    	printf(">>>隊列爲空!\n");
    	return 0;
    }
    Node *n=Q->next;
    Q->next=n->next;
    *e=n->data;
    free(n);
    Q->data--;
    if(Q->data==0){
    	R=Q;
    }
    return 1;
}
void main(){

	LinkQueue Q;  //L S Q T
	int choice;
    ElemType e;
	printf("----------單鏈隊列-----\n");
	print("1.初始化\n");
	printf("2.入隊\n");
	printf("3.出隊\n");
	printf("4.長度\n");
	printf("5.打印\n");
	printf("0.退出\n");
	while(1){
		printf(">>>請選擇:");
		scanf("%d",&choice);
		switch(choice){
			case 1:
			    break;
			case 2:
			    print(">>>請輸入入隊的元素:");
                scanf("%d",&e);
                enqueue(&Q,e);
			    break;
			case 3:
			    if(dequeue(&Q,e)){
			    	printf(">>>出隊元素爲%d",e);
			    }
			    break;
			case 4:
			    printf(">>>長度爲%d\n",Q.data);
			    break;
			case 5:
			    show(&Q);
			    break;
			case 0:
			    break;  
		}

	}
}