棧和線性表的簡單應用-數制轉換
阿新 • • 發佈:2019-01-05
棧結構具有後進先出的特點,是程式設計中的有用工具
我們先來看看進位制轉換的過程 如圖:
可以看出 整數部分符合後進先出的特點,可以應用棧結構
小數部分先進先出,可以應用線性表
棧的標頭檔案 sqstack.h
1 #pragma once 2 #include <stdio.h> 3 #include <stdlib.h> 4 #define STACK_INIT_SIZE 100//儲存空間初始分配量 5 #define STACKINCREMENT 10//儲存空間分配增量 6 #define OK 1 7#define ERROR 0 8 typedef int StackType; //棧元素型別 9 10 typedef struct { 11 StackType *base; //在構造之前和銷燬之後,base的值為NULL 12 StackType *top; //棧頂指標 13 int stacksize; //當前已分配的儲存空間,以元素為單位 14 }SqStack; //順序棧 15 16 //棧的初始化 17 int InitStack(SqStack *p) { 18 19 20 p->base = (StackType*)malloc(STACK_INIT_SIZE * sizeof(StackType)); 21 if (p->base == NULL) return ERROR; //記憶體分配失敗 22 p->top = p->base; //棧頂與棧底相同表示一個空棧 23 p->stacksize = STACK_INIT_SIZE; 24 return OK; 25 26 } 27 //判斷棧是否為空 28 int EmptyStack(SqStack *p) { 29 //若為空棧 則返回OK,否則返回ERROR 30 if (p->top == p->base) return OK; 31 else return ERROR; 32 } 33 //順序棧的壓入 34 int Push(SqStack *p, StackType e) { 35 //插入元素e為新的棧頂元素 36 if ((p->top - p->base) >= p->stacksize) //棧滿,追加儲存空間 37 { 38 p->base = (StackType*)realloc(p->base, (p->stacksize + STACKINCREMENT) * sizeof(StackType)); 39 if (p->base == NULL) return ERROR;// 儲存空間分配失敗 40 p->top = p->base + p->stacksize; //可能有人覺得這句有點多餘(我當時也是這麼想的 後面有解釋) 41 p->stacksize += STACKINCREMENT; 42 } 43 *(p->top) = e; 44 (p->top)++; 45 return OK; 46 } 47 // 順序棧的彈出 48 int Pop(SqStack *p, StackType *e) { 49 //若棧不空,則刪除p的棧頂元素,用e返回其值 50 if (p->top == p->base) return ERROR; 51 --(p->top); 52 *e = *(p->top); 53 return OK; 54 55 56 } 57 //順序棧的銷燬 58 int DestroyStack(SqStack *p) { 59 //釋放棧底空間並置空 60 free(p->base); 61 p->base = NULL; 62 p->top = NULL; 63 p->stacksize = 0; 64 65 return OK; 66 }
線性表的標頭檔案 sqlist.h
#pragma once //順序線性表 #include <stdio.h> #include <stdlib.h> #define LIST_INIT_SIZE 100 //線性表儲存空間的初始分配量 #define LISTINCREMENT 10 //線性表儲存空間的分配增量 #define OK 1 #define ERROR 0 typedef double ElemType; typedef struct { ElemType *elem; //儲存空間基地址 int length; //當前長度 int listsize; //當前分配的儲存容量(以sizeof(ElemType))為單位 }SqList; //順序表的初始化 void InitList(SqList *L) { L->elem = (ElemType*)malloc(LIST_INIT_SIZE); if (!L->elem) //儲存分配失敗 exit(-1); L->length = 0; //空表長度為0 L->listsize = LIST_INIT_SIZE; //初始儲存容量 } //判斷表是否為空 int EmptyList(SqList *L) { if (L->length == 0) { return OK; } return ERROR; } //尾插 int BackInsert(SqList *L,ElemType e) { ElemType *newbase, *p; if (L->length >= L->listsize) //當前儲存空間已滿,增加分配 { newbase = (ElemType*)realloc(L->elem, (L->listsize + LISTINCREMENT) * sizeof(ElemType)); if (!newbase) exit(-1); L->elem = newbase; //新基地址 L->listsize += LISTINCREMENT; //增加儲存容量 } p = L->elem + L->length; //p指向最後一個元素的後一個地址 *p = e; //插入e L->length++; //表長加1 return OK; } //打印表中元素 void PrintList(SqList *L) { int i; if (EmptyList(L)==OK) { printf("表為空!\n"); exit(-1); } for (i = 0; i< L->length; i++) { printf("%d ",*( L->elem+i)); } printf("\n"); } //銷燬表 int DestoryList(SqList *L) { free(L->elem); return OK; }
原始碼:
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <math.h> 4 #include "sqstack.h" //引入順序棧儲存結構及其基本操作 5 #include "sqlist.h" //引入順序表儲存結構及其基本操作 6 #define OK 1 7 #define ERROR 0 8 9 //對於輸入任意一個非負的十進位制數,列印與其等值的N進位制數 10 void Conversion(int N) { 11 double x, decimal; 12 int integer; 13 scanf("%lf", &x); 14 integer =(int)floor(x); //整數部分 15 decimal = x - integer; //小數部分 16 //處理整數部分 17 18 StackType *e; 19 SqStack *ps, s; 20 ps = &s; 21 e = (StackType*)malloc(sizeof(StackType)); //為指標e分配記憶體地址 22 InitStack(ps); //初始化棧 23 while (integer) //當integer不等於0 24 { 25 Push(ps, integer % N); //壓入integer 除以N的餘數 26 integer = integer / N; 27 } 28 while (EmptyStack(ps) != OK) //當棧不為空 29 { 30 Pop(ps, e); //彈出的棧頂元素,並讓e指向其地址 31 printf("%d ", *e); // 輸出e 每一個數碼間用空格隔開 32 } 33 //處理小數部分 34 if (decimal) { //小數部分不為0 才處理 35 SqList *L; 36 ElemType m; 37 L = (SqList*)malloc(sizeof(SqList)); //為指標L分配記憶體地址 38 InitList(L); //初始化順序表 39 while (decimal) //當decimal不為0 40 { 41 m = (ElemType)floor(decimal*N); 42 BackInsert(L, m); //插入decimal*N的整數 43 decimal = decimal * N - m; 44 } 45 printf(". "); 46 PrintList(L); //每一個數碼之間用空格隔開 47 } 48 } 49 int main() { 50 int N; 51 printf("請輸入目標進位制:"); 52 scanf("%d", &N); 53 printf("將十進位制數n轉換為%d進位制數,請輸入:n(>=0)=", N); 54 Conversion(N); 55 return 0; 56 57 }
合理的使用資料結構可以使程式碼跟易讀,易懂。棧的引入
簡化了程式設計的問題,劃分了不同的關注層次,邏輯思路清晰。