数据-第9课-静态链表

第9课- 静态链表

单链表完美解决了顺序表的问题!

还有其它改进顺序表的方法吗?

学生A:单链表很完美,我觉得顺序表可以退休了。

学生B:我也觉得 ,老师为什么还要教我们顺序表呢 ?

学生A:那不是为了展现单链表的强大嘛!

学生B:看来我们可以彻底抛弃顺序表了。

牛人小C出场。

顺序表有优势,单链表也同样有缺点!

学生C:单链表虽然综合起来胜过了顺序表,但是也有不足之处。

学生B:什么不足之处呢,Linux内核都用的单链表哦!

学生A:就是,一般的大型项目都能找到单链表的身影!

学生C:我想你们会明白的单链表的相对劣势,单链表的实现严重依赖指针!数据元素中必须包含一个额外的指针域!没有指针的程序设计语言无法实现!

一. 顺序表的改进

1. 静态链表的定义

(1)      顺序表数组中的元素由两个数据域组成:data和next。

(2)      data域用于存储数据。

(3)      next域用于存储下一个元素在数组中的下标。

2. 静态链表是在顺序表的基础上利用数组实现的单链表!

typedef struct _tag_StaticListNode

{

         unsigned int data;

         int next;  

}TStaticListNode;

结点结构体定义

typedef struct _tag_StaticList

{

         int capacity;

         TStaticListNode header;

         TStaticListNode node[];  

}TStaticList;

静态链表结构体定义

二. 静态链表操作

1. 获取第pos个元素操作

(1)      判断线性变是否合法。

(2)      判断位置是否合法。

(3)      由表头开始通过next域一定pos次后,当前元素的next域即要获取的元素在数组中的下标。

sList->node[0] = sList->header;

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

{

         current = sList->node[current].next;

}

object = sLit->node[current].next;

2. 插入元素到位置pos的算法

(1)      判断线性表是否合法。

(2)      判断插入位置是否合法。

(3)      在数组中查找空闲位置index。

(4)      由表头开始通过next域移动pos次后,当前元素的 ,当前元素的next域为要插入的位置。

(5)      将新元素插入。

(6)      线性表长度加1。

for(i=0; (i<pos) && (sList->node[current].next != 0); i++)

{

         current = sList->node[current].next;

}

sLisst->node[index].next = sLisst->node[current].next;

sLisst->node[current].next = index;

3. 删除第pos个元素的算法

(1)      判断线性表是否合法。

(2)      判断插入位置是否合法。

(3)      获取第pos个元素。

(4)      将第pos个元素从链表中删除。

(5)      线性表长度减1。

object = sLisst->node[current].next;

sLisst->node[current].next = sLisst->node[object].next;

三. 创建可复用静态链表

StaticList.h

#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

StaticList.c

#include <stdio.h>

#include <malloc.h>

#include "StaticList.h"

#define AVAILABLE -1

typedef struct _tag_StaticListNode

{

    unsigned int data;

    int next;

} TStaticListNode;

typedef struct _tag_StaticList

{

    int capacity;

    TStaticListNode header;

    TStaticListNode node[];

} TStaticList;

StaticList* StaticList_Create(int capacity) // O(n)

{

    TStaticList* ret = NULL;

    int i = 0;

   

    if( capacity >= 0 )

    {

        ret = (TStaticList*)malloc(sizeof(TStaticList) + sizeof(TStaticListNode) * (capacity + 1));

    }

   

    if( ret != NULL )

    {

        ret->capacity = capacity;

        ret->header.data = 0;

        ret->header.next = 0;

       

        for(i=1; i<=capacity; i++)

        {

            ret->node[i].next = AVAILABLE;

        }

    }

   

    return ret;

}

void StaticList_Destroy(StaticList* list) // O(1)

{

    free(list);

}

void StaticList_Clear(StaticList* list) // O(n)

{

    TStaticList* sList = (TStaticList*)list;

    int i = 0;

   

    if( sList != NULL )

    {

        sList->header.data = 0;

        sList->header.next = 0;

       

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

        {

            sList->node[i].next = AVAILABLE;

        }

    }

}

int StaticList_Length(StaticList* list) // O(1)

{

    TStaticList* sList = (TStaticList*)list;

    int ret = -1;

   

    if( sList != NULL )

    {

        ret = sList->header.data;

    }

   

    return ret;

}

int StaticList_Capacity(StaticList* list) // O(1)

{

    TStaticList* sList = (TStaticList*)list;

    int ret = -1;

   

    if( sList != NULL )

    {

        ret = sList->capacity;

    }

   

    return ret;

}

int StaticList_Insert(StaticList* list, StaticListNode* node, int pos)  // O(n)

{

    TStaticList* sList = (TStaticList*)list;

    int ret = (sList != NULL);

    int current = 0;

    int index = 0;

    int i = 0;

   

    ret = ret && (sList->header.data + 1 <= sList->capacity);

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

   

    if( ret )

    {

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

        {

            if( sList->node[i].next == AVAILABLE )

            {

                index = i;

                break;

            }

        }

       

        sList->node[index].data = (unsigned int)node;

       

        sList->node[0] = sList->header;

       

        for(i=0; (i<pos) && (sList->node[current].next != 0); i++)

        {

            current = sList->node[current].next;

        }

       

        sList->node[index].next = sList->node[current].next;

        sList->node[current].next = index;

       

        sList->node[0].data++;

       

        sList->header = sList->node[0];

    }

   

    return ret;

}

StaticListNode* StaticList_Get(StaticList* list, int pos)  // O(n)

{

    TStaticList* sList = (TStaticList*)list;

    StaticListNode* ret = NULL;

    int current = 0;

    int object = 0;

    int i = 0;

   

    if( (sList != NULL) && (0 <= pos) && (pos < sList->header.data) )

    {

        sList->node[0] = sList->header;

       

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

        {

            current = sList->node[current].next;

        }

       

        object = sList->node[current].next;

       

        ret = (StaticListNode*)(sList->node[object].data);

    }

   

    return ret;

}

StaticListNode* StaticList_Delete(StaticList* list, int pos) // O(n)

{

    TStaticList* sList = (TStaticList*)list;

    StaticListNode* ret = NULL;

    int current = 0;

    int object = 0;

    int i = 0;

   

    if( (sList != NULL) && (0 <= pos) && (pos < sList->header.data) )

    {

        sList->node[0] = sList->header;

       

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

        {

            current = sList->node[current].next;

        }

       

        object = sList->node[current].next;

       

        sList->node[current].next = sList->node[object].next;

       

        sList->node[0].data--;

       

        sList->header = sList->node[0];

       

        sList->node[object].next = AVAILABLE;

       

        ret = (StaticListNode*)(sList->node[object].data);

    }

   

    return ret;

}

main.c

#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);

   

    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 ", *p);

    }

   

    printf(" ");

   

    while( StaticList_Length(list) > 0 )

    {

        int* p = (int*)StaticList_Delete(list, 0);

       

        printf("%d ", *p);

    }

   

    printf(" ");

   

    StaticList_Insert(list, &x, 0);

    StaticList_Insert(list, &y, 0);

    StaticList_Insert(list, &z, 0);

   

    printf("Capacity: %d Length: %d ", StaticList_Capacity(list), StaticList_Length(list));

   

    for(index=0; index<StaticList_Length(list); index++)

    {

        int* p = (int*)StaticList_Get(list, index);

       

        printf("%d ", *p);

    }

   

    StaticList_Destroy(list);

   

         return 0;

}

小结

l  静态链表其实是单链表的另一种实现方式。

l  静态链表的实现“媒介”不是指针而是数组。

l  静态链表主要用于不支持指针的程序设计语言中。

l  静态链表的实现是一种内存管理的简易方法。

思考:为什么静态链表结构体中要再定义个header成员,而不直接使用node[0]?

原文地址:https://www.cnblogs.com/free-1122/p/11322736.html