六、栈的实现两种方式

前言:栈的特点:先进先出,只在栈顶进行操作。栈低密封,不进行操作,栈的实现有两种方式,通过对线性表实现进行复用。安全性高。

实现栈的方式:

第一种:以顺序结构的方式实现:将顺序表的队尾作为栈顶

第二种:以链式结构的方式实现:将链式表的队头作为栈顶

第一种实现方式(顺序结构):

1、SeqList.h

#ifndef _SEQLIST_H_

#define _SEQLIST_H_

typedef void SeqList;

typedef void SeqListNode;

SeqList* SeqList_Create(int capacity);

void SeqList_Destroy(SeqList* list);

void SeqList_Clear(SeqList* list);

int SeqList_Length(SeqList* list);

int SeqList_Capacity(SeqList* list);

int SeqList_Insert(SeqList* list, SeqListNode* node, int pos);

SeqListNode* SeqList_Get(SeqList* list, int pos);

SeqListNode* SeqList_Delete(SeqList* list, int pos);

#endif

2、SeqList.c

#include <stdio.h>

#include <malloc.h>

#include "SeqList.h"

typedef unsigned int TSeqListNode;

typedef struct _tag_SeqList

{

int capacity;

int length;

TSeqListNode* node;

} TSeqList;

SeqList* SeqList_Create(int capacity) // O(1)

{

TSeqList* ret = NULL;

if( capacity >= 0 )

{

ret = (TSeqList*)malloc(sizeof(TSeqList) + sizeof(TSeqListNode) * capacity);

}

if( ret != NULL )

{

ret->capacity = capacity;

ret->length = 0;

ret->node = (TSeqListNode*)(ret + 1);

}

return ret;

}

void SeqList_Destroy(SeqList* list) // O(1)

{

free(list);

}

void SeqList_Clear(SeqList* list) // O(1)

{

TSeqList* sList = (TSeqList*)list;

if( sList != NULL )

{

sList->length = 0;

}

}

int SeqList_Length(SeqList* list) // O(1)

{

TSeqList* sList = (TSeqList*)list;

int ret = -1;

if( sList != NULL )

{

ret = sList->length;

}

return ret;

}

int SeqList_Capacity(SeqList* list) // O(1)

{

TSeqList* sList = (TSeqList*)list;

int ret = -1;

if( sList != NULL )

{

ret = sList->capacity;

}

return ret;

}

int SeqList_Insert(SeqList* list, SeqListNode* node, int pos) // O(n)

{

TSeqList* sList = (TSeqList*)list;

int ret = (sList != NULL);

int i = 0;

ret = ret && (sList->length + 1 <= sList->capacity);

ret = ret && (0 <= pos);

if( ret )

{

if( pos >= sList->length )

{

pos = sList->length;

}

for(i=sList->length; i>pos; i--)

{

sList->node[i] = sList->node[i-1];

}

sList->node[i] = (TSeqListNode)node;

sList->length++;

}

return ret;

}

SeqListNode* SeqList_Get(SeqList* list, int pos) // O(1)

{

TSeqList* sList = (TSeqList*)list;

SeqListNode* ret = NULL;

if( (sList != NULL) && (0 <= pos) && (pos < sList->length) )

{

ret = (SeqListNode*)(sList->node[pos]);

}

return ret;

}

SeqListNode* SeqList_Delete(SeqList* list, int pos) // O(n)

{

TSeqList* sList = (TSeqList*)list;

SeqListNode* ret = SeqList_Get(list, pos);

int i = 0;

if( ret != NULL )

{

for(i=pos+1; i<sList->length; i++)

{

sList->node[i-1] = sList->node[i];

}

sList->length--;

}

return ret;

}

3、SeqStack.h

#ifndef _SEQSTACK_H_

#define _SEQSTACK_H_

typedef void SeqStack;

SeqStack* SeqStack_Create(int capacity);

void SeqStack_Destroy(SeqStack* stack);

void SeqStack_Clear(SeqStack* stack);

int SeqStack_Push(SeqStack* stack, void* item);  //stack确定哪个栈,item地址

void* SeqStack_Pop(SeqStack* stack);

void* SeqStack_Top(SeqStack* stack);

int SeqStack_Size(SeqStack* stack);

int SeqStack_Capacity(SeqStack* stack);

#endif

4、SeqStack.c

#include "SeqStack.h"

#include "SeqList.h"

SeqStack* SeqStack_Create(int capacity)  //创建栈

{

return SeqList_Create(capacity);   //创建线性表

}

void SeqStack_Destroy(SeqStack* stack)   //销毁栈

{

SeqList_Destroy(stack);        //通过线性表函数的复用,销毁栈

}

void SeqStack_Clear(SeqStack* stack) //清空栈中的所有元素

{

SeqList_Clear(stack);

}

int SeqStack_Push(SeqStack* stack, void* item)  //元素压入栈中;将栈顶对应着队尾

{

return SeqList_Insert(stack, item, SeqList_Length(stack));  //stack为栈的地址,item为元素的地址,seqList_Length从队尾插入

}

void* SeqStack_Pop(SeqStack* stack)  //出栈

{

return SeqList_Delete(stack, SeqList_Length(stack) - 1);

}

void* SeqStack_Top(SeqStack* stack)  //获取栈顶元素

{

return SeqList_Get(stack, SeqList_Length(stack) - 1);

}

int SeqStack_Size(SeqStack* stack)   //获取栈的元素个数

{

return SeqList_Length(stack);

}

int SeqStack_Capacity(SeqStack* stack) //获取栈的内存容量

{

return SeqList_Capacity(stack);

}

5、main.c

#include <stdio.h>

#include <stdlib.h>

#include "SeqStack.h"

/* run this program using the console pauser or add your own getch, system("pause") or input loop */

int main(int argc, char *argv[])

{

SeqStack* stack = SeqStack_Create(20);  //创建一个有20元素大小的栈

int a[10];

int i = 0;

for(i=0; i<10; i++)  //依次将10个元素压入栈中

{

a[i] = i;

SeqStack_Push(stack, a + i);

}

printf("Top: %d\n", *(int*)SeqStack_Top(stack));

printf("Capacity: %d\n", SeqStack_Capacity(stack));

printf("Length: %d\n", SeqStack_Size(stack));

while( SeqStack_Size(stack) > 0 )  //依次输出出栈的元素

{

printf("Pop: %d\n", *(int*)SeqStack_Pop(stack));

}

SeqStack_Destroy(stack);

return 0;

}

第二种方式(链式方式)

1、LinkList.h

#ifndef _LINKLIST_H_

#define _LINKLIST_H_

typedef void LinkList;

typedef struct _tag_LinkListNode LinkListNode;

struct _tag_LinkListNode

{

LinkListNode* next;

};

LinkList* LinkList_Create();

void LinkList_Destroy(LinkList* list);

void LinkList_Clear(LinkList* list);

int LinkList_Length(LinkList* list);

int LinkList_Insert(LinkList* list, LinkListNode* node, int pos);

LinkListNode* LinkList_Get(LinkList* list, int pos);

LinkListNode* LinkList_Delete(LinkList* list, int pos);

#endif

2、LinkList.c

#include <stdio.h>

#include <malloc.h>

#include "LinkList.h"

typedef struct _tag_LinkList

{

LinkListNode header;

int length;

} TLinkList;

LinkList* LinkList_Create() // O(1)

{

TLinkList* ret = (TLinkList*)malloc(sizeof(TLinkList));

if( ret != NULL )

{

ret->length = 0;

ret->header.next = NULL;

}

return ret;

}

void LinkList_Destroy(LinkList* list) // O(1)

{

free(list);

}

void LinkList_Clear(LinkList* list) // O(1)

{

TLinkList* sList = (TLinkList*)list;

if( sList != NULL )

{

sList->length = 0;

sList->header.next = NULL;

}

}

int LinkList_Length(LinkList* list) // O(1)

{

TLinkList* sList = (TLinkList*)list;

int ret = -1;

if( sList != NULL )

{

ret = sList->length;

}

return ret;

}

int LinkList_Insert(LinkList* list, LinkListNode* node, int pos) // O(n)

{

TLinkList* sList = (TLinkList*)list;

int ret = (sList != NULL) && (pos >= 0) && (node != NULL);

int i = 0;

if( ret )

{

LinkListNode* current = (LinkListNode*)sList;

for(i=0; (i<pos) && (current->next != NULL); i++)

{

current = current->next;

}

node->next = current->next;

current->next = node;

sList->length++;

}

return ret;

}

LinkListNode* LinkList_Get(LinkList* list, int pos) // O(n)

{

TLinkList* sList = (TLinkList*)list;

LinkListNode* ret = NULL;

int i = 0;

if( (sList != NULL) && (0 <= pos) && (pos < sList->length) )

{

LinkListNode* current = (LinkListNode*)sList;

for(i=0; i<pos; i++)

{

current = current->next;

}

ret = current->next;

}

return ret;

}

LinkListNode* LinkList_Delete(LinkList* list, int pos) // O(n)

{

TLinkList* sList = (TLinkList*)list;

LinkListNode* ret = NULL;

int i = 0;

if( (sList != NULL) && (0 <= pos) && (pos < sList->length) )

{

LinkListNode* current = (LinkListNode*)sList;

for(i=0; i<pos; i++)

{

current = current->next;

}

ret = current->next;

current->next = ret->next;

sList->length--;

}

return ret;

}

3、LinkStack.h

#ifndef _LINKSTACK_H_

#define _LINKSTACK_H_

typedef void LinkStack;

LinkStack* LinkStack_Create();  //创建栈

void LinkStack_Destroy(LinkStack* stack);  //销毁栈

void LinkStack_Clear(LinkStack* stack);   //清空栈

int LinkStack_Push(LinkStack* stack, void* item);  //进栈

void* LinkStack_Pop(LinkStack* stack);  //出栈

void* LinkStack_Top(LinkStack* stack);  //获取栈顶元素

int LinkStack_Size(LinkStack* stack);  //获取栈大小

#endif

4、LinkStack.c

#include <malloc.h>

#include "LinkStack.h"

#include "LinkList.h"

typedef struct _tag_LinkStackNode

{

LinkListNode header;

void* item;

} TLinkStackNode;

LinkStack* LinkStack_Create()   //创建栈

{

return LinkList_Create();

}

void LinkStack_Destroy(LinkStack* stack)   //销毁栈

{

LinkStack_Clear(stack);

LinkList_Destroy(stack);

}

void LinkStack_Clear(LinkStack* stack)  //清空栈

{

while( LinkStack_Size(stack) > 0 )   //判断栈中是否有元素,若有则执行出栈动作

{

LinkStack_Pop(stack);

}

}

int LinkStack_Push(LinkStack* stack, void* item)  //进栈 ,item为进栈元素的地址

{

TLinkStackNode* node = (TLinkStackNode*)malloc(sizeof(TLinkStackNode));  //动态内存分配

int ret = (node != NULL) && (item != NULL);

if( ret )  //判断栈与压入栈的元素是否合法

{

node->item = item;

ret  = LinkList_Insert(stack, (LinkListNode*)node, 0);  //压入队头

}

if( !ret )

{

free(node);

}

return ret;

}

void* LinkStack_Pop(LinkStack* stack)  //出栈

{

TLinkStackNode* node = (TLinkStackNode*)LinkList_Delete(stack, 0);

void* ret = NULL;

if( node != NULL )

{

ret = node->item;

free(node);

}

return ret;

}

void* LinkStack_Top(LinkStack* stack)   //获取栈顶元素

{

TLinkStackNode* node = (TLinkStackNode*)LinkList_Get(stack, 0);

void* ret = NULL;

if( node != NULL )

{

ret = node->item;

}

return ret;

}

int LinkStack_Size(LinkStack* stack)   //获取栈的大小

{

return LinkList_Length(stack);

}

5、main.c

#include <stdio.h>

#include <stdlib.h>

#include "LinkStack.h"

/* run this program using the console pauser or add your own getch, system("pause") or input loop */

int main(int argc, char *argv[])

{

LinkStack* stack = LinkStack_Create();

int a[10];

int i = 0;

for(i=0; i<10; i++)

{

a[i] = i;

LinkStack_Push(stack, a + i);  //a+i为压入栈中元素的地址

}

printf("Top: %d\n", *(int*)LinkStack_Top(stack));

printf("Length: %d\n", LinkStack_Size(stack));

while( LinkStack_Size(stack) > 0 )

{

printf("Pop: %d\n", *(int*)LinkStack_Pop(stack));

}

LinkStack_Destroy(stack);

return 0;

}

时间: 2024-10-10 16:18:37

六、栈的实现两种方式的相关文章

python全栈脱产第34天------开启进程的两种方式、join方法、进程对象其他相关的属性和方法、僵尸进程、孤儿进程、守护进程、互斥锁

一.开启进程的两种方式 方式一: from multiprocessing import Processimport time def task(name): print('%s is running' %name) time.sleep(3) print('%s is done' %name) # 在windows系统上,开启子进程的操作必须放到if __name__ == '__main__'的子代码中if __name__ == '__main__': p=Process(target=t

第六篇、文件处理之文件修改的两种方式

目录 第六篇.文件处理之文件修改的两种方式 说明 方式一 方式二 总结 第六篇.文件处理之文件修改的两种方式 说明 文件的数据是存放在硬盘上的,所以只能覆盖,不能直接修改,平时看到的修改文件都是障眼法的效果,具体的两种实现方式 方式一 将硬盘里的文件全部加载到内存里,内存是可以直接修改的,修改完了后,再由内存覆盖到硬盘里 import os with open('37r.txt') as fr, open('37r_swap.txt', 'w') as fw: data = fr.read()

遍历获得磁盘文件的两种方式

在winform中可能有这种情况,遍历某一个文件夹得到当前文件夹中的所有文件以及子文件夹中的所有文件,以此类推,然后添加到一个TreeView控件中,或者通过控制台输出文件以及文件夹的名称.方法多种多样,下面说的是通过递归和队列的方式来进行.递归其实就是在函数调用的时候进行压栈进行的,所以可以概述为通过栈和队列来实现. 递归方式实现 private void GetAllFile (string strPath,TreeNode parentNode) { //得到当前路径下的所有文件和文件夹

POI操作Excel详解,HSSF和XSSF两种方式

HSSF方式: package com.tools.poi.lesson1; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.text.ParseException; import java.text.SimpleDateFormat; import java.

strus2中获取表单数据 两种方式 属性驱动 和模型驱动

strus2中获取表单数据 两种方式 属性驱动 和模型驱动 属性驱动 /** * 当前请求的action在栈顶,ss是栈顶的元素,所以可以利用setValue方法赋值* 如果一个属性在对象栈,在页面上可以根据name属性进行回显*/ /** * 属性驱动实现的条件:* 1.当前请求的action在栈顶,所以action中的属性就暴漏出来了* 2.获取页面上表单的元素,整合成一个map * 3.调用setValue方法赋值*/ 1 package cn.itcast.struts2.sh; 2 3

OC--定义字符串的两种方式

1.常量区 存放一些常量字符串2.堆 对象3.栈 存放局部变量 掌握:1.定义字符串的两种方式 1>利用数组 char name[] = "itcast"; 特点:字符串里面的字符是可以修改的 2>利用指针 char *name = "itcast"; 特点:字符串其实是一个常量字符串,里面的字符是不能修改的

内存分配原理 -进程分配内存的两种方式,分别有系统调用完成brk() 和mmap()(不设计共享内存)

如何查看进程发生缺页中断的次数? 用ps -o majflt,minflt -C program命令查看. majflt代表major fault,中文名叫大错误,minflt代表minor fault,中文名叫小错误.           这两个数值表示一个进程自启动以来所发生的缺页中断的次数. 发成缺页中断后,执行了那些操作? 当一个进程发生缺页中断的时候,进程会陷入内核态,执行以下操作: 1.检查要访问的虚拟地址是否合法 2.查找/分配一个物理页 3.填充物理页内容(读取磁盘,或者直接置0

Python之面向对象的组合、多态、菱形问题、子类中重用父类的两种方式

一.组合 ''' 1.什么是组合 组合就是一个类的对象具备某一个属性,该属性的值是指向另外一个类的对象 2.为何用组合 组合也是用来解决类与类直接代码冗余问题的 3.如何用组合 ''' # 继承减少代码冗余,但是将类与类进行了强耦合,python不崇尚,所以能不用继承就尽量不用继承 class OldboyPeople: school = 'oldboy' def __init__(self, name, age, sex): self.name = name self.age = age se

Spark Streaming 读取 Kafka 数据的两种方式

在Spark1.3之前,默认的Spark接收Kafka数据的方式是基于Receiver的,在这之后的版本里,推出了Direct Approach,现在整理一下两种方式的异同. 1. Receiver-based Approach val kafkaStream = KafkaUtils.createDstream(ssc, [zk], [consumer group id], [per-topic,partitions] ) 2. Direct Approach (No Receivers) v