单链表部分
#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_Delete(LinkList* list,int pos);
LinkListNode* LinkList_Get(LinkList* list,int pos);
#endif
#include <stdio.h>
#include <malloc.h>
#include "LinkList.h"
typedef struct _tag_LinkList{//表头结构体
LinkListNode header;//表头指针,header是一个结构体,成员是一个指针
int length;//链表长度成员,在这里没有直接定义链表节点成员
}TLinkList;
LinkList* LinkList_Create()
{
TLinkList* ret = (TLinkList*)malloc(sizeof(TLinkList));//动态分配空间,刚刚创建的时候只需要分配表头的空间
if(ret != NULL){
ret->length = 0;//对长度初始化为0
ret->header.next = NULL; //对表头指针成员初始化为NULL
}
return ret;//返回表头地址
}
void LinkList_Destroy(LinkList* list)
{
free(list);
}
void LinkList_Clear(LinkList* list)
{
TLinkList* sList = (TLinkList*)list;
if(sList != NULL){//让表头恢复到刚刚创建的状态
sList->length = 0;
sList->header.next = NULL;
}
}
int LinkList_Length(LinkList* list)
{
TLinkList* sList = (TLinkList*)list;//除了destroy函数,其余函数基本上都会用到强制类型转换
int ret = -1;
if(sList != NULL){//如果合法则返回当前长度
ret = sList->length;
}
return ret;
}
int LinkList_Insert(LinkList* list,LinkListNode* node,int pos)
{
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;//成功插入返回1否则返回0
}
LinkListNode* LinkList_Get(LinkList* list,int pos)
{
TLinkList* sList = (TLinkList*)list;
LinkListNode* ret = NULL;
int i = 0;
if((sList != NULL) && (pos >= 0) && (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)
{
TLinkList* sList = (TLinkList*)list;
LinkListNode* ret = NULL;
int i = 0;
if((sList != NULL) && (pos >= 0) && (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;
}
链式栈部分
#ifndef __LINKSTACK_H__
#define __LINKSTACK_H__
typedef void LinkStack;
LinkStack* LinkStack_Create();
void LinkStack_Destroy(LinkStack* stack);
void LinkStack_Clear(LinkStack* stack);
int LinkStack_Size(LinkStack* stack);
int LinkStack_Push(LinkStack* stack,void* item);
void* LinkStack_Pop(LinkStack* stack);
void* LinkStack_Top(LinkStack* stack);
#endif
#include <malloc.h>
#include "LinkList.h"
#include "LinkStack.h"
typedef struct _tag_LinkStackNode{//定义栈里面每个数据元素的结构体
LinkListNode header;//为了和单链表的节点匹配
void* item;//实际的存放数据的成员(实际上存放的是数据在内存中的地址)
}TLinkStackNode;
LinkStack* LinkStack_Create()
{
return LinkList_Create();
}
void LinkStack_Destroy(LinkStack* stack)
{
LinkStack_Clear(stack);//由于每一次插入都有申请空间的操作,所以不能直接free,应该将在建立栈以后申请的空间逐一清空再free
LinkList_Destroy(stack);//当栈里面没有数据以后就可以释放申请的空间
}
void LinkStack_Clear(LinkStack* stack)//将所有数据弹出栈
{
while(LinkStack_Size(stack) > 0){//通过判断栈的大小来确定是否还有数据存在
LinkStack_Pop(stack);
}
}
int LinkStack_Size(LinkStack* stack)
{
return LinkList_Length(stack);
}
int LinkStack_Push(LinkStack* stack,void* item)
{
TLinkStackNode* node = (TLinkStackNode*)malloc(sizeof(TLinkStackNode));//每次新数据进栈都要重新为其申请空间
int ret = (stack != NULL) && (node != NULL) && (item != NULL);//合法性检测
if(ret){
node->item = item;//将要进栈的数据传递给申请出来的新空间的item成员
ret = LinkList_Insert(stack,(LinkListNode*)node,0);//头插法链表的头部是栈顶
}
if(!ret){//如果进栈没有成功则要把之前为之申请的空间释放
free(node);
}
return ret;//成功返回1否则返回0
}
void* LinkStack_Pop(LinkStack* stack)
{
TLinkStackNode* node = (TLinkStackNode*)LinkList_Delete(stack,0);//将栈顶元素弹出,实际上就是删除链表的第一个节点
void* ret = NULL;
if(node != NULL){
ret = node->item;//返回栈顶元素的数据成员(存放数据的地址)
}
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;
}
测试程序
#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);
}
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;
}