静态链表

来源:互联网 发布:鲸藤壶 知乎 编辑:程序博客网 时间:2024/05/16 07:52
这个说的是针对没有指针的程序设计语言,但是实现的过程明显用到了结构体指针。。。。。。还有不知道为什么要用一个header,直接用node【0】难道不可以吗,没发现非得用临时变量啊!!
#include <stdio.h>#include <stdlib.h>#include "StaticList.h" /* run this program using the console pauser or add your own getch, system("pause") or input loop */int main(int argc, char *argv[]) {StaticList* list = StaticList_Create(10);//创建一个可以容纳10个元素的静态链表         int index = 0;        int i = 0;    int j = 1;    int k = 2;    int x = 3;    int y = 4;    int z = 5;        StaticList_Insert(list, &i, 0);    StaticList_Insert(list, &j, 0);    StaticList_Insert(list, &k, 0);        for(index=0; index<StaticList_Length(list); index++)    {        int* p = (int*)StaticList_Get(list, index);                printf("%d\n", *p);    }        printf("\n");        while( StaticList_Length(list) > 0 )    {        int* p = (int*)StaticList_Delete(list, 0);                printf("%d\n", *p);    }        printf("\n");        StaticList_Insert(list, &x, 0);    StaticList_Insert(list, &y, 0);    StaticList_Insert(list, &z, 0);        printf("Capacity: %d Length: %d\n", StaticList_Capacity(list), StaticList_Length(list));        for(index=0; index<StaticList_Length(list); index++)    {        int* p = (int*)StaticList_Get(list, index);                printf("%d\n", *p);    }        StaticList_Destroy(list);    return 0;}
#ifndef __STATICLIST_H__#define __STATICLIST_H__typedef void StaticList;typedef void StaticListNode;StaticList* StaticList_Create(int capacity);void StaticList_Destroy(StaticList* list);void StaticList_Clear(StaticList* list);int StaticList_Length(StaticList* list);int StaticList_Capacity(StaticList* list);int StaticList_Insert(StaticList* list,StaticListNode* node,int pos);StaticListNode* StaticList_Get(StaticList* list,int pos);StaticListNode* StaticList_Delete(StaticList* list,int pos);#endif

#include <stdio.h>#include <malloc.h> #include "StaticList.h"#define AVAILABLE  -1typedef struct _tag_StaticListNode{//节点结构体定义 unsigned int data;//节点的数据成员 int next;//节点的指示成员,代表下一个节点在链表中的位置,如果为AVAILABLE则表示该节点是空闲可用的 }TStaticListNode;typedef struct _tag_StaticList{//链表(表头)结构体定义 int capacity;//链表容量。因为是基于数组实现的,所以要指定容量 TStaticListNode header;//头结点,包含了长度的信息和第一个节点的位置 TStaticListNode node[];//node【0】比较特殊,和header有很大联系,是他将长度信息传递给header }TStaticList;StaticList* StaticList_Create(int capacity){TStaticList* ret = NULL;int i = 0;if(capacity >= 0)ret = (TStaticList*)malloc(sizeof(TStaticList) + sizeof(TStaticListNode)*(capacity+1));//node[0]不作为实际的数据节点,所以要多申请一个节点的空间来存放实际的节点数据 if(ret != NULL){ret->capacity = capacity;ret->header.data = 0;//头节点里面的数据成员和位置成员都为0 ret->header.next = 0; for(i = 0;i <= capacity;i++){//注意给每个node成员的next成员赋值的次数是capacity+1次,使得他们被标记为空闲可用 ret->node[i].next = AVAILABLE; }}return ret;//返回链表(表头)的地址 }void StaticList_Destroy(StaticList* list){free(list); }void StaticList_Clear(StaticList* list){TStaticList* sList = (TStaticList*)list;int i = 0;if(sList != NULL){sList->header.data = 0;//头节点里面的数据成员和位置成员都恢复为0 sList->header.next = 0; for(i = 0;i <= sList->capacity;i++){//注意给每个node成员的next成员赋值的次数是capacity+1次,使得他们被重新标记为空闲可用 sList->node[i].next = AVAILABLE; }}}int StaticList_Length(StaticList* list){TStaticList* sList = (TStaticList*)list;int ret = -1;if(sList != NULL){ret = sList->header.data;//header里面的data成员存放的就是长度信息。而node[0]则作为长度信息的中间变量 }return ret;}int StaticList_Capacity(StaticList* list){TStaticList* sList = (TStaticList*)list;int ret = -1;if(sList != NULL){ret = sList->capacity;//直接返回容量信息 }return ret;}int StaticList_Insert(StaticList* list,StaticListNode* node,int pos){TStaticList* sList = (TStaticList*)list;int ret = (sList != NULL) && (node != NULL) && (pos >= 0) && (sList->header.data < sList->capacity);//合法性检测 int  i = 0;int index = 0;//标记可用节点在链表中的位置 int current = 0;//当前节点的位置 if(ret){for(i = 1;i <= sList->capacity;i++){//遍历链表找出可用的节点,一旦找到第一个就退出循环 if(AVAILABLE == sList->node[i].next){index = i;//将可用节点的位置传递给index break;}}sList->node[index].data = (unsigned int)node;//将要插入的数据的地址传递给链表节点的数据成员 sList->node[0] = sList->header;//将长度信息传递给node[0] for(i = 0;(i < pos) && (sList->node[current].next != 0);i++){//移动cureent使得当前节点的next指向的位置就是要插入新数据的位置,而且为了防止pos大于现有长度,所以要做修正 current = sList->node[i].next;//i在0到pos-1范围内变化,一共最多移动pos次 } sList->node[index].next = sList->node[current].next;//当是空链表的时候直接从这里执行 sList->node[current].next = index;sList->node[0].data++;//更新长度信息sList->header = sList->node[0];//因为node[0]只是一个中间变量,所以要将长度信息再次保存到header } return ret;//成功插入返回1否则返回0 }StaticListNode* StaticList_Get(StaticList* list,int pos){TStaticList* sList = (TStaticList*)list;StaticListNode* ret = NULL;int i = 0;int current  = 0;int object = 0;if((sList != NULL) && (pos >= 0) && (pos < sList->header.data)){//合法性检测 sList->node[0] = sList->header;//在每一次移动current之前都应该给node[0]赋值 for(i = 0; i < pos;i++){//移动current current = sList->node[current].next;//每次都是以current作为基准来移动,不是i。i不代表下标,只控制移动的次数 }object = sList->node[current].next;//取出要获取的节点在链表中的下标 ret = (StaticListNode*)sList->node[object].data;//通过之前得到的下标找到该节点的数据成员(实际上是内存地址) }return ret;}StaticListNode* StaticList_Delete(StaticList* list,int pos){TStaticList* sList = (TStaticList*)list;StaticListNode* ret = NULL;int i = 0;int current  = 0;int object = 0;if((sList != NULL) && (pos >= 0) && (pos < sList->header.data)){//合法性检测 sList->node[0] = sList->header;//在每一次移动current之前都应该给node[0]赋值 for(i = 0; i < pos;i++){//移动current current = sList->node[i].next;}object = sList->node[current].next;//取出要删除的节点在链表中的下标 sList->node[current].next = sList->node[object].next;//更换当前节点的next成员达到删除的目的 sList->node[0].data--;//更新长度信息 sList->node[object].next = AVAILABLE;//使被删除的节点变成空闲可用 sList->header = sList->node[0];//将node[0]重新更新header成员,保存长度信息等 ret = (StaticListNode*)sList->node[object].data;//通过之前得到的下标找到该节点的数据成员(实际上是内存地址) }return ret;}


0 0