C語言實現棧(基於結構體指針)

本文章利用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;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章