本文章利用C語言,實現了基於結構體元素的棧,主要功能包括:棧初始化、判斷棧空、清除棧中所有元素、出棧、入棧、判斷棧滿、讀取棧頂元素、棧中當前元素個數、多次出棧、棧元素反轉、棧頂元素唯一入棧、棧搜索、棧當前容量。
棧作爲一個最簡單的數據結構,實現起來也非常容易,想想現在有一摞盤子,每次只能取走或放一個盤子且只能最上面進行操作;
本文主要包括三種棧:棧容量固定棧、可以擴大容量的棧、既可以擴大也可以縮小容量的棧。分別如下圖所示:
主要的函數定義如下:
具體的C語言代碼如下:
#ifndef STACK_H
#define STACK_H
#include <stdbool.h>
// Please do not change anything in header file //
// struct definition for each element in stack
struct Element {
int key;
char* value;
};
typedef struct Element Element;
// struct definition for stack
struct Stack {
int top;
int capacity;
float growthFactor;
float shrinkFactor;
bool dynamic;
Element** elements;
};
typedef struct Stack Stack;
// set of functions for stack
Stack* makeStack(int cap);
Stack* makeStackG(int cap, float growF);
Stack* makeStackGnS(int cap, float growF, float shrinkF);
Element* pop(Stack* s);
Element** multiPop(Stack* s, int k);
bool push(Stack* s, int k, char* v);
bool pushUnique(Stack* s, int k, char* v);
void reverse(Stack* s); // resizable
Element* peek(Stack* s);
int search(Stack* s, int k, char* v);
int getCapacity(Stack* s);
bool isFull(Stack* s);
void clear(Stack* s);
void cleanStack(Stack* s);
int currentSize(Stack* s);
bool isEmpty(Stack* s);
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include "stack.h"
// Edit only after this line //
//struct Stack stack;
// pop function for stack
Element* pop(Stack* s){
float filledRatio=1.0*currentSize(s)/getCapacity(s);
if (isEmpty(s))
return NULL;
if(s->dynamic) {
if( s->shrinkFactor > 0.0 && filledRatio<=s->shrinkFactor ) {
int newcapacity = (int)(s->capacity*0.5);
s->capacity = newcapacity;
s->elements = realloc(s->elements, sizeof(Element*)*newcapacity);
Element* e=s->elements[s->top-1];
//free(s->elements[s->top-1]);
s->top--;
return e;
}
else {
Element* e=s->elements[s->top-1];
free(s->elements[s->top-1]);
s->top--;
return e;
}
}
else{
Element* e=s->elements[s->top-1];
free(s->elements[s->top-1]);
s->top--;
return e;
}
}
// multipop: pop multiple elements from stack
Element** multiPop(Stack* s, int k){
int curr=currentSize(s);
Element** E= malloc(sizeof(Element*)*curr);
//int i=0;
if(isEmpty(s))
return NULL;
if(k<curr ){
for(int i=0; i<k; i++ ){
for(int j=curr; j>(curr - k); j--){
E[i]= s->elements[j];
}
pop(s);
}
}
else{
for(int i=0; i<curr; i++ ){
for(int j=curr; j >= 0; j--){
E[i]= s->elements[j];
}
pop(s);
}
}
return E;
}
// Utility function: add element for push
// This function is a hint, you may ignore its implementation
void addE(Stack* s, int k, char* v) {
}
// Utility function: expandCapacity for push
// This function is a hint, you may ignore its implementation
void expandCapacity(Stack* s) {
}
// push function for stack
bool push(Stack* s, int k, char* v){
Element* element = malloc(sizeof(Element));
element->key = k;
element->value = v;
//float filledRatio=0.0;
//if (getCapacity(s)>0)
float filledRatio=1.0*currentSize(s)/getCapacity(s);
//if (s->growthFactor>0)
if(isFull(s)){
return false;
}
if(s->dynamic){
if(s->growthFactor>0.0 && filledRatio >= s->growthFactor) {
int newcapacity = (int)(2*(s->capacity));
s->elements = realloc(s->elements, sizeof(Element*)*newcapacity);
s->capacity = newcapacity;
s->elements[s->top] = element;
s->top++;
return true;
}
else {
s->elements[s->top] = element;
s->top++;
return true;
}
}
else{
s->elements[s->top] = element;
s->top++;
return true;
}
}
// push unique function for stack
bool pushUnique(Stack* s, int k, char* v){
Element* e=peek(s);
if(e->key==k && e->value==v){
return false;
}
else {
if(push(s,k,v)){
return true;
}
else{
return false;
}
}
}
// reverse the elements in stack
void reverse(Stack* s){
int cap=s->top;
Element** E=multiPop(s,s->top);
int j;
for(j=0; j<cap; j++) {
push(s,E[j]->key,E[j]->value);
}
}
// peek function for stack
Element* peek(Stack* s){
if (isEmpty(s)) {
return NULL;
}
else {
return s->elements[s->top-1];
}
}
// search for element from top of stack
int search(Stack* s, int k, char* v){
int size=currentSize(s);
int i;
for(i=0; i<size; i++) {
if (s->elements[s->top-1-i]->key==k && s->elements[s->top-1-i]->value==v) {
return i+1;
}
}
return -1;
}
// get current capacity of stack
int getCapacity(Stack* s){
return s->capacity;
}
//check if stack is full
bool isFull(Stack* s){
if(s->top == getCapacity(s)) {
return true;
}
else
return false;
}
// clear the stack
void clear(Stack *s) {
s->top=0;
}
// clean the stack
void cleanStack(Stack *s) {
for(int i = 0; i < s->capacity; i++) {
free(s->elements[i]);
}
free(s->elements);
free(s);
}
// current size of stack
int currentSize(Stack* s){
return s->top;
}
// check if stack empty
bool isEmpty(Stack* s){
if (s->top==0)
return true;
else
return false;
}
// Stack with fixed capacity
Stack* makeStack(int cap){
Stack*s = malloc(sizeof(Stack));
s->top=0;
s->capacity = cap;
s->growthFactor=0.0;
s->shrinkFactor=0.0;
s->dynamic=false;
s->elements = malloc(sizeof(Element*)*cap);
return s;
}
// Stack that can grow,0.5<=growF<=1.0
Stack* makeStackG(int cap, float growF){
Stack*s = malloc(sizeof(Stack));
s->top=0;
s->capacity = cap;
s->growthFactor=growF;
s->shrinkFactor=0.0;
s->dynamic=true;
s->elements = malloc(sizeof(Element*)*cap);
return s;
}
// Stack that can grow and shrink
// 0.5<=growF<=1.0, 0 < shrinkF <= 0.5
Stack* makeStackGnS(int cap, float growF, float shrinkF){
Stack*s = malloc(sizeof(Stack));
s->top=0;
s->capacity = cap;
s->growthFactor=growF;
s->shrinkFactor=shrinkF;
s->dynamic=true;
s->elements = malloc(sizeof(Element*)*cap);
return s;
}
// print stack item list
void printStack(Stack* s){
printf("Stack item list:\n");
int i;
for(i=0; i< s->top; i++) {
printf("item:(%d,%s)\n",s->elements[s->top-1-i]->key,s->elements[s->top-1-i]->value);
}
}
int main(int argc, const char* argv[]) {
Stack*s=makeStack(5);
//makeStackG(5,0.5);
//Stack* s = makeStackGnS(5,0.7,0.3);
isEmpty(s);
push(s,1,"aaa");
printf("s->elements[0]:%d %s\n",s->elements[0]->key,s->elements[0]->value);
push(s,2,"bbb");
printf("s->elements[1]:%d %s\n",s->elements[1]->key,s->elements[1]->value);
push(s,4,"ddd");
push(s,5,"eee");
push(s,6,"fff");
push(s,7,"ggg");
push(s,8,"hhh");
printStack(s);
pushUnique(s,5,"eee");
pop(s);
pop(s);
peek(s);
pushUnique(s,5,"eee");
multiPop(s,3);
printStack(s);
reverse(s);
printStack(s);
search(s,3,"ccc");
search(s,2,"fcc");
clear(s);
isEmpty(s);
return 0;
}