栈的应用—数制转换

501 阅读3分钟

把一个十进制的数转换为一个二进制的数,例如 9 转换为二进制是 1001,可以使用栈来实现。

我们知道不同数制之间的转换是这样进行的,除数取余,按顺序来

比如 :(9)十进制=(1001)二进制

9/2= 4....1 4/2=2.....0 2/2=1.....0 1/2=0.....1

然后就是倒着排,即1001,这是结果,与顺着排的正好相反,所以可以使用先进后出的栈来表示

代码如下:

void conversion(){
 initStack(S);   //初始化栈
 scanf("%d",&N);  //输入非负十进制整数
 while(N!=0)
 { 
     Push(S,(N%2));  //这里的2是二进制,你可以改变,入栈,
     N=N/2; 
}
 
 while(!StackEmpty) 
 { 
      Pop(S,e); //栈顶元素出栈并赋值于e
      printf("%d",e);
 }
}

如果代码写完整就是这样的:

#include <stdlib.h>
#include <stdio.h>
#define MaxSize 1024

/*定义顺序栈*/
typedef int ElemType;

typedef struct SqStack
{
    ElemType data[MaxSize];
    int top;
}SqStack;

//初始化 
SqStack * InitStack()
{  
   SqStack *S;
    S=(SqStack *)malloc(sizeof(SqStack));
    if(S==NULL) exit(0); //申请失败 
    S->top=-1; //栈顶指针
    return S;
}

//判空 
bool StackEmpty(SqStack *S)
{
    if(S->top==-1) //栈空
    return true;
    else 
    return false;//栈不空
}


//入栈
bool Push(SqStack *S,ElemType e)
{
     if(S->top==MaxSize-1)
     return false; //栈满了
     
     S->top+=1;            //指针先+1
     S->data[S->top]=e;     //数组top元素e——入栈
      return true;
}


//出栈 
bool Pop(SqStack *S,ElemType *e)
{
	if(S->top==-1)
	return false;//栈空
    else           
{	*e=S->data[S->top]; //栈顶元素先出栈
	S->top-=1;        //指针减1
	return true;
}
}

//进制转换算法 
void conversion(int &N){
	int e; 
 SqStack *S=InitStack();//初始化一个顺序栈S
  
 while(N>0)
 { 
     Push(S,(N%2));  //这里的2是二进制,你可以改变,入栈,
     N=N/2; 
 }
      while(!StackEmpty(S))  //栈不为空
 { 
      Pop(S,&e); //栈顶元素出栈并赋值于e
      printf("%d",e);
 }
}


int main()
{
    int N;
    
    printf("请输入一个非负整数:\n");
    scanf("%d", &N);
    printf("转换后的数为:\n");
    conversion(N);
}

图片.png

关于如果用链栈实现的方法,和混合使用的方法见:


如果我想加一个菜单,来实现指定10进制到几进制的转换:比如10到8

还是在上面加个cover_number代替2就行:

图片.png 图片.png

图片.png

图片.png


这个程序现在也只能实现 十进制到其他进制的转换,还是很局限的,只是因为十进制到其他进制的转换正好符合栈的先进后出特点,所以很适合使用,也可以用数组实现,那样空间复杂度会降低,但是用栈实现时,其逻辑过程更清楚。

数组实现就是顺序表or数组得到每个%余数,然后保存数组,最后倒序输出,链表也是,最后逆置


下面实现下试试十进制转换为十六进制的链栈,注意十六进制需要考虑输出现实大于9的十六进制位数,比如ABCDEF

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

/*定义链栈*/
typedef int elemtype;
typedef struct LinkedStackNode
{
    elemtype data;
    struct LinkedStackNode *next;
}LinkedStackNode, *LinkedStack;

//LinkedStack top;

/*链栈的初始化*/
LinkedStack Init_LinkedStack()
{
    LinkedStack top = (LinkedStackNode *)malloc(sizeof(LinkedStackNode)); //头结点 

    if(top != NULL)
    {
        top->next = NULL;
    }
    return top;
}

/*判栈空*/
int LinkedStack_Empty(LinkedStack top)
{
    if (top->next == NULL)
    {
        return 1;
    }
    else
    {
        return 0;
    }
    
}

/*入栈*/
int Push_LinkedStack(LinkedStack top, elemtype x)
{
    LinkedStackNode *node;
    node = (LinkedStackNode *)malloc(sizeof(LinkedStackNode));  

    if (node == NULL)
    {
        return 0;
    }
    else
    {
        node->data = x;
        node->next = top->next;
        top->next = node;
        return 1;
    }
    
}

/*出栈*/
int Pop_LinkedStack(LinkedStack top, elemtype * x)
{
    LinkedStackNode *node; 
    if (top->next == NULL)
    {
        return 0;
    }
    else
    {
        node = top->next;
        *x = node->data;
        top->next = node->next;
        free(node);
        return 1;
    }
    
}

/*进制转换*/
void ListStackConversion(int N)
{
    int x;
    LinkedStack S = Init_LinkedStack();
    while (N > 0)
    {
        Push_LinkedStack(S, N % 16);
        N = N / 16;
    }
    while (! LinkedStack_Empty(S))
    {
        Pop_LinkedStack(S, &x);
        /*判断ABCDEF*/
		switch(x)
		{
		 case 10:
            printf("A");
            break;
        case 11:
            printf("B");
            break;
        case 12:
            printf("C");
            break;
        case 13:
            printf("D");
            break;
        case 14:
            printf("E");
            break;
        case 15:
            printf("F");
            break;
        default:
            printf("%d", x);
            break;	
		}
        
    }
    
}

int main()
{
    int N;
    printf("请输入要转换的数值:\n");
    scanf("%d", &N);
    printf("转换后数值为:\n");
    ListStackConversion(N);
}

图片.png

图片.png