1. 程式人生 > >棧和線性表的簡單應用-數制轉換

棧和線性表的簡單應用-數制轉換

  棧結構具有後進先出的特點,是程式設計中的有用工具

我們先來看看進位制轉換的過程 如圖:

可以看出 整數部分符合後進先出的特點,可以應用棧結構

小數部分先進先出,可以應用線性表

   棧的標頭檔案 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 }

   合理的使用資料結構可以使程式碼跟易讀,易懂。棧的引入

簡化了程式設計的問題,劃分了不同的關注層次,邏輯思路清晰。