栈的基本实现
#include <stdio.h>
#include <stdlib.h> //malloc,realloc
#include <string.h>
#include <stdbool.h> // bool
typedef int stack_item;
/**
@brief 栈的结构定义
@struct
*/
typedef struct stack_t
{
int size; //栈的实际大小
int capacity; //栈的容量,以元素为单位
stack_item* elemment; //栈的存储数组
}stack_t;
/**
@brief 创建栈
@param capacity 初始容量
@return 指向栈对象的指针
*/
stack_t* stack_create(const int capacity)
{
stack_t * s = (stack_t*)malloc(sizeof(stack_t)); //分配内存
s->capacity = capacity;
s->size = 0;
s->elemment = (stack_item*)malloc(capacity*sizeof(stack_item));
return s;
}
/*
@brief 销毁栈
@param s 指向栈对象的指针
*/
void stack_destroy(stack_t *s)
{
free(s->elemment); //先释放栈的存储数组
free(s);//然后释放栈
}
/**
@brief 判断栈是否为空
@return 是否为空 ,是空 返回true,否则 false
*/
bool stack_empty(const stack_t *s)
{
return s->size == 0;
}
/*
@brief 获取栈的元素个数
*/
int stack_size(const stack_t *s)
{
if (s == NULL)
return 0;
return s->size;
}
/*
@brief 进栈
@param s 指向栈对象的指针
@param x 要进栈的元素
*/
void stack_push(stack_t *s, const stack_item x)
{
if (s == NULL)
return;
//栈已满,重新分配内存.将栈的容量扩大为2倍
if (s->size == s->capacity)
{
stack_item* temp = (stack_item*)realloc(s->elemment, s->capacity * 2 * sizeof(stack_item));
s->capacity *= 2;
s->elemment = temp;
}
s->elemment[s->size++] = x;
}
/*
@brief 出栈
*/
void stack_pop(stack_t *s)
{
if (s == NULL)
return;
s->size--;
}
/*
@brief 获取栈顶元素
@return 栈顶元素
*/
stack_item stack_top(const stack_t *s)
{
return s->elemment[s->size - 1];
}
/**
@brief 打印栈 ,只针对基本元素类型,方便测试
*/
void stack_print(const stack_t *s)
{
if (s == NULL)
return;
for (int i = 0; i < s->size;i++)
{
printf_s("%d\t", s->elemment[i]);
}
puts("\n");
}
int main()
{
stack_t* test = stack_create(5);
stack_push(test, 2);
stack_push(test, 3);
stack_push(test, 4);
stack_push(test, 5);
stack_print(test);
puts("test 1 **************************************\n");
stack_pop(test);
stack_print(test);
printf_s("%d\n",stack_top(test));
stack_destroy(test);
return 0;
}
栈的特点
-
基本操作push和pop的时间复杂度为常数级别O(1)
常见的使用场景是
- 后缀表达式求值
- 中缀-后缀转换
汉诺塔问题
#include <stdio.h>
#include <stack>
/**
* @author 韦轩
* @time 2015/07/11
* @brief 将塔座x 上按直径从小到大且自上而下编号为1 至n 的n 个圆盘按规则搬到塔座z 上,y 可用做辅助塔座
* @param[n] 圆盘个数
* @param[x] 源塔柱
* @param[y] 辅助柱
* @param[z] 目标塔柱
* @return 无
*
*/
//递归实现
void hanoi_With_Recursion(int n, char x, char y, char z)
{
if (n == 1)
{
printf_s("%d from %c to %c\n", n,x,z);
}
else
{
/* 将x 上编号1 至n-1 的圆盘移到y,z 作辅助塔*/
hanoi_With_Recursion(n - 1, x, z, y);
/* 将编号为n 的圆盘从x 移到z */
printf("%d from %c to %c\n", n, x, z);
/* 将y 上编号1 至n-1 的圆盘移到z,x 作辅助塔*/
hanoi_With_Recursion(n - 1, y, x, z);
}
}
int main()
{
int n;
scanf_s("%d", &n);
printf_s("%d\n", (1 << n) - 1); /* 总次数*/
hanoi_With_Recursion(n, 'A', 'B', 'C');
return 0;
}
-
进制转换
-
将10进制转换成不大于16进制的任意进制
- 将任意进制转换成10进制
/**
* @author 韦轩
* @time 2015/07/11
* @brief 进制转换,将一个10 进制整数转化为d 进制,d<=16.
* @param n 十进制数
* @param d 进制
* @return 无
*/
void convert_int2other(int n, const int d)
{
std::stack<int> temp;
int e;
while (n != 0)
{
e = n%d;
temp.push(e);
n /= d;
}
while (!temp.empty())
{
e = temp.top();
temp.pop();
printf_s("%X", e);
}
return;
}
/**
* @author 韦轩
* @time 2015/07/11
* @brief 将一个d 进制整数转化为10 进制,d<=16.
* @param d 源字符串的进制
* @return 返回转换的结果
* 1C(16) = 1*16^1+12*16^0(2)
*/
int convert_other2int(const char s[],const int d)
{
int result = 0;
int temp = 0;
for (int i = 0; s[i] != '\0'; i++)
{
if (s[i] >= '0' && s[i] <= '9')
{
temp = s[i] - '0';
}
else if (s[i] >= 'A' && s[i] <= 'F')
{
temp = s[i] - 'A' + 10;
}
else
{
temp = s[i] - 'a' + 10;
}
result = result * d + temp;
}
return result;
}