激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

香港云服务器
服務器之家 - 編程語言 - C/C++ - 用C語言遞歸實現火車調度算法詳解

用C語言遞歸實現火車調度算法詳解

2022-02-21 15:119Uard1an C/C++

本文主要介紹了用C語言遞歸實現火車調度算法詳解,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下

筆者在李云清版的《數據結構》中第二章遇到了這道經典的火車調度題,經過對一些前輩的代碼進行學習,以下將這段火車代碼進行分析詳解,不對之處,還請各位大佬指示,不勝感激!

1、代碼

題目如下:
2.8編號為1,2,3,4的四列火車通過一個棧式的列車調度站,可能得到的調度結果有哪些?如果有n列火車通過調度站,請設計一個算法,輸出所有可能的調度結果。

算法運用的思想是運用棧+遞歸,算法的難點也在于此。先上代碼:

#include <stdio.h>
#define MAX 100
typedef struct s{
	char a[MAX];
	int top;
}Stack;/*定義棧的數據*/
/*定義一些全局變量*/
Stack S;/*定義全局性的棧*/

char d[MAX],seq[MAX];
/*d[MAX]用于存儲原始入棧序列,seq[MAX]用于存儲輸出序列*/
int len;/*定義將通過棧的元素個數*/ 
int count=0;/* 用于統計輸出序列的個數  */

void initStack(Stack *S) /*初始化空棧*/
{
	S->top=-1;
}

void push(Stack *S,char x) /*進棧*/
{
	if(S->top>=MAX) return;
	S->top++;
	S->a[S->top]=x;
}

char pop(Stack *S) /*出棧*/
{
	if (S->top==-1) 
	{ printf("ERROR, POP Empty Stack");  
	return -1; 
  }  
	S->top--;    
	return S->a[S->top+1];  
} 

int isEmpty(Stack *S)/*判斷棧是否為空*/  
{     
	if (S->top==-1) return 1; 
	return 0; 
} 

void outSeq(char *seq, int len)/*輸出頂點序列*/  
{    
	int i; 
	for(i=0; i<len; i++)  
	printf("%2c",seq[i]); 
	printf("\n"); 
} 

void scheduler(int pos, int seq_pos)
{    /* pos: 處理到原始數據中的第pos個元素, 
seq_pos:若出棧,應放在當前輸出數組的第seq_pos個位置 
*/ 
	int i=0;char t; 
/*對任何一個數,總是先進棧,再出棧。另外,這里不需要循環,類似于"查找數組中元素"用遞歸*/ 
	if(pos<len){
		/*一個數進棧后,有兩種處理方式:要么立刻出棧,要么進行下一個數的進棧*/ 
	push(&S,d[pos]); 
	scheduler(pos+1,seq_pos); 
	pop(&S); 
	} 
	if (!isEmpty(&S)){/*一個數出棧后,有兩種處理方式:要么繼續出棧,要么繼續下一個數的進
	棧*/ 
	t=pop(&S); 
	seq[seq_pos++]=t; 
	scheduler(pos,seq_pos); 
	push(&S,t); 
	} 
	if (pos>=len && isEmpty(&S))  
	{ outSeq(seq,len); count++; } 
}

int main(){ 
 int i; 
 printf("\nplease input the num be scheduled: "); 
 scanf("%d", &len); /*用len存儲待調度的火車數量*/ 
 for(i=0; i<len; i++) 
   d[i]='1'+i; /*創建火車編號,如a、b、c、...等*/ 
 printf("the original seq is:"); 
 outSeq(d,len); 
 initStack(&S); 
 scheduler(0,0); 
 printf("\n count=%d", count); 
 return 0; 
} 

輸入3(即三列火車),得到的結果如下:

用C語言遞歸實現火車調度算法詳解

 

2、代碼詳解

本算法主要是運用了棧+遞歸+回溯的思想,主要的代碼塊有三個:
代碼塊1

if(pos<len){	
	push(&S,d[pos]); 
	scheduler(pos+1,seq_pos); 
	pop(&S); 
	} 

代碼塊2

if (!isEmpty(&S)){
	t=pop(&S); 
	seq[seq_pos++]=t; 
	scheduler(pos,seq_pos); 
	push(&S,t); 
	}

代碼塊3

if (pos>=len && isEmpty(&S))  
	{ outSeq(seq,len); count++; } 

這里需要注意的是判定元素pos,是處理原始數據中第pos個元素,pos從0開始
代碼塊1根據你輸入的len和第pos個元素來判定是否執行代碼塊1
例如當你輸入了3,
通過代碼

scanf("%d", &len);
 for(i=0; i<len; i++) 
   d[i]='1'+i; 

即有三列火車,分別代號為1,2,3
數組d中的位置分別是0,1,2

當代碼第一次執行

void scheduler(int pos, int seq_pos)

函數的時候,進入了判定
此時參數pos和seq_pos都為0
那么0<len=3,執行代碼塊1
代碼塊1把數組第0個元素壓入棧中,即1號火車進入車站

接著進行第一次調用函數scheduler

此時參數pos為1,seq_pos為0
因為1<3,繼續執行代碼塊1
代碼塊1把數組第1個元素壓入棧中,即2號火車進入車站

進行第二次調用函數scheduler

此時參數pos為2,seq_pos為0
因為2<3,繼續執行代碼塊1
代碼塊1把數組第2個元素壓入棧中,即3號火車進入車站

進行第三次調用函數scheduler

此時參數pos為3,seq_pos為0
因為3=len=3,所以開始執行代碼塊2

在代碼塊2中,把棧頂的元素賦值給t,同時把t放入seq數組的第0個位置中,seq++
即3號列車駛出火車站

進行第四次調用函數sceduler

此時參數pos=3,seq_pos=1
繼續執行代碼塊2,把棧頂的元素賦值給t,同時把t放入seq數組的第1個位置中,seq++
即2號列車駛出火車站

進行第五次調用函數sceduler

此時參數pos=3,seq_pos=2
繼續執行代碼塊2,把棧頂的元素賦值給t,同時把t放入seq數組的第2個位置中,seq++
即1號列車駛出火車站

進行第六次調用函數scheduler

此時參數pos=3,seq_pos=3,現在的情況是三列火車都已經駛出火車站了,也就是棧已經空了,同時滿足pos>=len的條件,所以執行代碼塊3

代碼塊3把結果進行了輸出,
輸出結果是3,2,1
第六次調用函數scheduler整個過程結束

此時,代碼開始進行回溯

回到了第五次調用函數scheduler
代碼塊2中scheduler執行完,執行push,也就是壓棧操作,可是現在已經沒有火車進站了,因為三列火車都已經走了

代碼回到了第四次調用函數scheduler
代碼塊2中scheduler執行完,執行push,也就是壓棧操作,也沒有火車能進車站了
為什么?
還記不記得這個時候是3號列車和2號列車已經出去了,1號列車在車站里,所以沒有多余的進站的車了

代碼代碼回到了第三次調用函數scheduler
還記不記得這個時候是3號列車、已經出去了,1號列車和2號列車在車站里,所以沒有多余的進站的車了

代碼代碼回到了第二次調用函數scheduler

代碼重新回到了代碼塊1

注意,是代碼塊1

此時,執行了pop,也就是進行了出棧操作
什么意思?
棧頂的3號列車駛出了車站

這里是筆者出現了思維誤區的地方,讀者不理解遞歸思想的需要特別注意,當時我在想,3號列車駛出后是不是回到了第一次調用函數?忽略了下面的if語句,錯誤的認為執行了代碼塊1后不會執行代碼塊2,混淆了if-else和if,if語句的關系

代碼1執行完,開始執行代碼2
注意此時的列車只有兩輛,是1號列車和2號列車,參數是pos=2,seq_pos=0

代碼塊2進行了出棧操作,讓在棧頂的2號列車出車站,然后seq_pos++

進行第七次調用函數sceduler

此時代碼參數pos=2,seq_pos=1
pos=2<len=3,進入代碼塊1
代碼塊1把pos=2的元素壓入棧中
什么意思?
把三號列車駛入車站

進行第八次調用函數sceduler

此時代碼參數pos=3,seq_pos=1
pos=3=len=3,進入代碼塊2
代碼塊2進行了出棧操作,讓在棧頂的3號列車出車站
然后seq_pos++

進行第九次調用函數scheduler

此時代碼參數pos=3,seq_pos=2
pos=3=len=3,進入代碼塊2
代碼塊2進行了出棧操作,讓在棧頂的1號列車出車站
然后seq_pos++

進行第十次調用函數scheduler

pos=3=len=3,同時棧里的三輛列車已經全部駛出車站了,所以進行執行代碼塊3
代碼塊3把結果進行了輸出
輸出結果是2,3,1

以此類推…

 

3、用二叉樹表示調用過程

左子樹表示壓棧(進站),右子樹表示出棧(駛出車站),線上數字表示調用函數次數,負數表示出棧,例如-1表示1號列車駛出車站

用C語言遞歸實現火車調度算法詳解

 

4、思維導圖

用C語言遞歸實現火車調度算法詳解

本文代碼參考自李云清《數據結構》第三版課本習題火車調度算法答案

本文有參考作者@littlehedgehog的火車調度詳解,但作者@littlehedgehog并未對代碼塊1中pop的作用和代碼塊2中push進行分析,在此表示感謝

到此這篇關于用C語言遞歸實現火車調度算法詳解的文章就介紹到這了,更多相關用C語言遞歸實現火車調度算法詳解內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!

原文鏈接:https://blog.csdn.net/weixin_44001222/article/details/121207987

延伸 · 閱讀

精彩推薦
  • C/C++C++之重載 重定義與重寫用法詳解

    C++之重載 重定義與重寫用法詳解

    這篇文章主要介紹了C++之重載 重定義與重寫用法詳解,本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內容,需要的朋友可以參考下...

    青山的青6062022-01-04
  • C/C++C語言實現電腦關機程序

    C語言實現電腦關機程序

    這篇文章主要為大家詳細介紹了C語言實現電腦關機程序,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    xiaocaidayong8482021-08-20
  • C/C++C/C++經典實例之模擬計算器示例代碼

    C/C++經典實例之模擬計算器示例代碼

    最近在看到的一個需求,本以為比較簡單,但花了不少時間,所以下面這篇文章主要給大家介紹了關于C/C++經典實例之模擬計算器的相關資料,文中通過示...

    jia150610152021-06-07
  • C/C++c++ 單線程實現同時監聽多個端口

    c++ 單線程實現同時監聽多個端口

    這篇文章主要介紹了c++ 單線程實現同時監聽多個端口的方法,幫助大家更好的理解和學習使用c++,感興趣的朋友可以了解下...

    源之緣11542021-10-27
  • C/C++深入理解goto語句的替代實現方式分析

    深入理解goto語句的替代實現方式分析

    本篇文章是對goto語句的替代實現方式進行了詳細的分析介紹,需要的朋友參考下...

    C語言教程網7342020-12-03
  • C/C++學習C++編程的必備軟件

    學習C++編程的必備軟件

    本文給大家分享的是作者在學習使用C++進行編程的時候所用到的一些常用的軟件,這里推薦給大家...

    謝恩銘10102021-05-08
  • C/C++C語言中炫酷的文件操作實例詳解

    C語言中炫酷的文件操作實例詳解

    內存中的數據都是暫時的,當程序結束時,它們都將丟失,為了永久性的保存大量的數據,C語言提供了對文件的操作,這篇文章主要給大家介紹了關于C語言中文件...

    針眼_6702022-01-24
  • C/C++詳解c語言中的 strcpy和strncpy字符串函數使用

    詳解c語言中的 strcpy和strncpy字符串函數使用

    strcpy 和strcnpy函數是字符串復制函數。接下來通過本文給大家介紹c語言中的strcpy和strncpy字符串函數使用,感興趣的朋友跟隨小編要求看看吧...

    spring-go5642021-07-02
1071
主站蜘蛛池模板: 欧美成人午夜精品久久久 | 久久久久久久国产a∨ | 欧美特级黄色 | 成人激情在线 | 中文字幕11 | 成人毛片免费看 | 欧美一级淫片免费视频1 | 国产精品视频中文字幕 | 国产在线免| 国产成人精品视频在线 | 久国产精品视频 | 成人免费毛片一 | 国产一级小视频 | 青青草好吊色 | 爽妇网国产精品 | 色婷婷久久久 | 久久天堂| 国产精品欧美日韩一区二区 | 深夜影院一级毛片 | 91 在线免费观看 | 日韩午夜一区二区三区 | 91精品国产综合久久男男 | 欧美91看片特黄aaaa | 伊人一二三四区 | 色综合久久久久久久久久久 | 羞羞羞网站 | 日本中文字幕久久 | 性生活香蕉视频 | 毛片av网址 | 精品一区二区免费 | 日本高清无遮挡 | 91九色蝌蚪国产 | 九九综合视频 | 毛片免| 国产精品午夜未成人免费观看 | 在线a亚洲视频播放在线观看 | 亚洲国产精品一区二区三区 | 日本欧美一区二区三区在线观看 | 国产999精品久久久久 | 91在线观看 | 国产二区三区在线播放 |