【数据结构】Liner-List 线性表(更新时间:2016-04-06)

来源:互联网 发布:飞鱼网络电视tv版 编辑:程序博客网 时间:2024/05/16 18:55

【数据结构】Liner-List 线性表(更新时间:2016-04-06)

趁着室友刚刚开始学习数据结构,赶紧配合着他的进度来写关于数据结构的相关内容
博文中的代码均使用C++语法,部分代码(主要是函数重载等)无法在C语言环境下编译

线性表 是最简单、最基本也是最常用的数据结构,它是以数组为基础定义的使得所需要的 元素存储空间 一一对应的一种数据结构,即每一个存储元素都对应于一个特定的存储位置。

常见的线性表是用数组来存储,也就是我们常说的顺序存储:

struct ListNode;                        //定义线性表表头节点typedef ListNode* PtrToNode;            //定义线性表表头指针typedef PtrToNode LinerList;            //重定义表头指针typedef int ElementType;                //重定义数据类型struct ListNode                         //数据结构描述{           int capacity;                       //表的容量     int tail;                           //指向当前表的尾部    ElementType* Element;               //数据域};const int MAX_CAP = 100;                //初始容量

示意图:

线性存储链表示意图

基础操作

初始化

将线性表初始化,通过指针操作,将表头地址传入初始化函数,并以指针的形式返回表头。初始化表的容量以及表的尾指针。

LinerList Initial( void )                                                           //表的初始化{    LinerList L = NULL;    L = ( LinerList ) malloc ( sizeof(ListNode) );                                  //分配表头地址    L->capacity = MAX_CAP;                                                          //初始化数值域空间    L->tail = 0;                                                                    //表尾部指针指向表头    L->Element = ( ElementType* ) malloc( L->capacity * sizeof( ElementType ) );    //分配数值域地址    return L;                                                                       //返回表头}

删除表

将整个线性表删除,表头置为空指针

void Delete( LinerList L )                                                          //表的删除{    if( L != NULL )    {        free( L->Element );                                                         //释放数值域空间        free( L );                                                                  //释放表头        L = NULL;                                                                   //表头置空    }}

扩充表

在我们向线性表中插入数据的时候,由于线性表的有限性,会出现线性表容量溢出的情况,在这种情况下,我们可以使用realloc函数来达到重新分配数值空间的目的。

LinerList Expansion( LinerList L )                                                  //表的扩容{    L->capacity++;                                                                  //容量扩充    L->Element = ( ElementType* ) realloc ( L->Element, L->capacity * sizeof( ElementType ) );  //重分配数据空间}

查找

对于线性表,我们经常需要查询其中是否存在某特定的元素。

int Find( const LinerList L, const ElementType X )                                  //查找元素{    int pos = 0;                                                                    //游标初始化    while( L->Element[pos] != X && pos < L->tail )                                  //游标遍历搜索        pos++;    if( pos != L->tail )                                                            //如果找到返回pos        return pos;    else        return 0;}

插入元素

对于线性表的插入主要分为简单插入和定点插入两种(使用函数重载来进行插入类别的判断):
简单插入 是指直接在表的尾部插入元素,如果表已满,则对表进行扩容。

LinerList Insert( LinerList L, const ElementType X )                                //简单插入{    if( L->tail == L->capacity )                                                    //判断是否过载        Expansion( L );                                                             //扩容    L->Element[ L->tail++ ] = X;                                                    //插入    return L;                                                                       //返回表头}

定点插入 是指插入位置与表的容量和表尾的相对状况进行插入,当插入位置在表尾内,则插入元素,如果插入位置非法,则返回原表。

LinerList Insert( LinerList L, const ElementType X, const int Pos )                 //定点插入{    int p = L->tail;                                                                //游标指向表尾    if( Pos > L->tail )                                                             //判断插入位置合法性    {        cout << "Wrong insert position!\n";        return L;    }    if( L->tail == L->capacity )                                                    //判断是否过载    {        Expansion( L );        L->tail++;    }    for( ; p > Pos; p-- )                                                           //将数值逐个后移        L->Element[p+1] = L->Element[p];    L->Element[p] = X;                                                              //插入}

删除元素

在线性表的使用过程中,除了插入一些元素之外,我们还需要删除一些元素。删除顺序线性表的方法是使用后面的元素填充到前面的元素之中。插入也分为简单删除和定点删除。由于代码中的Element类型为int,故暂时无法使用函数重载来在同一个代码区实现。
简单删除 调用代码中的Find函数来查找所要删除的元素是否出现在表中,如果出现则删除。

LinerList Delete( LinerList L, const ElementType X )                                //简单删除{    int pos = Find( L, X );                                                         //游标初始化    if( !pos )                                                                      //未找到指定元素    {        cout << X << " is not found in the LinerList!\n";        return L;    }    else    {        L->tail--;                                                                  //尾表前移        while( pos < L->tail )                                                      //元素逐个前移            L->Element[pos] = L->Element[pos+1];        return L;    }}

定点删除 同定点插入。

LinerList Delete( LinerList L, const int Pos )                                      //定点删除{    int p = Pos;    if( Pos > L->tail || Pos < 0 )                                                  //判断是否越界    {        cout << "Wrong deletion postion!\n";        return L;    }    L->tail--;                                                                      //尾标前移    while( p < L->tail )                                                            //元素逐个前移        L->Element[p] = L->Element[p+1];    return L;}

打印表

在使用线性表的时候我们会需要将表格打印出来,在这里简单示例用空格隔开每个元素。

void Print( const LinerList L )                                                     //打印表{    int pos = 0;                                                                    //游标初始化    if( L == NULL )    {        cout << "Empty List!\n";        return;    }    while( pos < L->tail )    {        cout << L->Element[pos] << ' ';                                             //打印元素并添加空格        pos++;    }    cout << endl;                                                                   //输出换行}

代码示例

注:其中的一个删除元素的函数被注释掉了,不体现实际功能

#include <cstdio>#include <cstdlib>#include <iostream>using namespace std;/*********************************************************/struct ListNode;                        //定义线性表表头节点typedef ListNode* PtrToNode;            //定义线性表表头指针typedef PtrToNode LinerList;            //重定义表头指针typedef int ElementType;                //重定义数据类型struct ListNode                         //数据结构描述{           int capacity;                       //表的容量     int tail;                           //指向当前表的尾部    ElementType* Element;               //数据域};const int MAX_CAP = 100;                //初始容量/*********************************************************/void        Delete( LinerList L );                                      //表的删除LinerList   Initial( void );                                            //表的初始化LinerList   Expansion( LinerList L );                                   //表的扩充int         Find( const LinerList L, const ElementType X );             //查找元素LinerList   Insert( LinerList L, const ElementType X );                 //简单插入LinerList   Insert( LinerList L, const ElementType X, const int Pos );  //定点插入LinerList   Delete( LinerList L, const ElementType X );                 //简单删除LinerList   Delete( LinerList L, const int Pos );                       //定点删除void        Print( const LinerList L );                                 //打印表/*********************************************************/int main(){    LinerList L;    ElementType X;    int i;    L = Initial();    for( i = 0; i < MAX_CAP-1; i++ )        Insert( L, i );    Insert( L, 99 );    Insert( L, 100, 100 );    Print( L );    Insert( L, 101, 102 );    Delete( L, 103 );    Delete( L );}/*********************************************************/void Delete( LinerList L )                                                          //表的删除{    free( L->Element );                                                             //释放表的数值域空间    free( L );                                                                      //释放表头    L = NULL;                                                                       //表头置空}LinerList Initial( void )                                                           //表的初始化{    LinerList L = NULL;    L = ( LinerList ) malloc ( sizeof(ListNode) );                                  //分配表头地址    L->capacity = MAX_CAP;                                                          //初始化数值域空间    L->tail = 0;                                                                    //表尾部指针指向表头    L->Element = ( ElementType* ) malloc( L->capacity * sizeof( ElementType ) );    //分配数值域地址    return L;                                                                       //返回表头}LinerList Expansion( LinerList L )                                                  //表的扩容{    L->capacity++;                                                                  //容量扩充    L->Element = ( ElementType* ) realloc ( L->Element, L->capacity * sizeof( ElementType ) );  //重分配数据空间}int Find( const LinerList L, const ElementType X )                                  //查找元素{    int pos = 0;                                                                    //游标初始化    while( L->Element[pos] != X && pos < L->tail )                                  //游标遍历搜索        pos++;    if( pos != L->tail )                                                            //如果找到则返回pos        return pos;    else        return 0;}LinerList Insert( LinerList L, const ElementType X )                                //简单插入{    if( L->tail == L->capacity )                                                    //判断是否过载        Expansion( L );                                                             //扩容    L->Element[ L->tail++ ] = X;                                                    //插入    return L;                                                                       //返回表头}LinerList Insert( LinerList L, const ElementType X, const int Pos )                 //定点插入{    int p = L->tail;                                                                //游标指向表尾    if( Pos > L->tail )                                                             //判断插入位置合法性    {        cout << "Wrong insert position!\n";        return L;    }    if( L->tail == L->capacity )                                                    //判断是否过载    {        Expansion( L );        L->tail++;    }    for( ; p > Pos; p-- )                                                           //将数值逐个后移        L->Element[p+1] = L->Element[p];    L->Element[p] = X;                                                              //插入}LinerList Delete( LinerList L, const ElementType X )                                //简单删除{    int pos = Find( L, X );                                                         //游标初始化    if( !pos )                                                                      //未找到指定元素    {        cout << X << " is not found in the LinerList!\n";        return L;    }    else    {        L->tail--;                                                                  //尾表前移        while( pos < L->tail )                                                      //元素逐个前移            L->Element[pos] = L->Element[pos+1];        return L;    }}/*LinerList Delete( LinerList L, const int Pos )                                      //定点删除{    int p = Pos;    if( Pos > L->tail || Pos < 0 )                                                  //判断是否越界    {        cout << "Wrong deletion postion!\n";        return L;    }    L->tail--;                                                                      //尾标前移    while( p < L->tail )                                                            //元素逐个前移        L->Element[p] = L->Element[p+1];    return L;}*/void Print( const LinerList L )                                                     //打印表{    int pos = 0;                                                                    //游标初始化    if( L == NULL )    {        cout << "Empty List!\n";        return;    }    while( pos < L->tail )    {        cout << L->Element[pos] << ' ';                                             //打印元素并添加空格        pos++;    }    cout << endl;                                                                   //输出换行}
1 0
原创粉丝点击