线性表的创建和基本操作

&&逻辑与 ||逻辑或

线性表是最基本、最简单、也是最常用的一种数据结构。

线性表结构中,数据元素之间通过一对一首位相接的方式连接起来。

具体实现时,线性表可

以采用不同的存储策略。

线性表的创建和基本操作_第1张图片

该方案将线性表存储在一片连续的空间里,通过data,len , 和max三个属性元素。

组织成为了一个结构:

  • data: 给出线性存储空间的起始地址;
  • max : 指明线性表存储空间最
  • len : 当前线性表里的数据元素个数。

为了讨论简化,我们假设每个数据元素是一个整数:

该线性表的结构定义如下:
struct SeqList{
    T* data; //数据元素存储空间的开始地址
    int len; //线性表的当前长度
    int max; //线性表的最大长度
};

以上示意图中的slist是指向给结构的一个指针,只要给定slist指针,就可对线性表就行操作。

对数据元素进行操作处理是一个数据结构的重要组成部分。线性表涉及的主要操作如下:

 SeqList*SL_Create(int max)

  • 释放线性表存储空间: 释放slist->data 指向的用于存储线性表数据元素的存储空间。该操作函数具体定义如下:

void SL_Free(SeqList*slist)

  • 置空线性表:将当前线性表变为一个空表,实现方法是将slist->len 设置为0。该操作函数具体定义如下:

void SL_MakeEmpty(SeqList*slist)

  • 获取线性表当前长度:获取并返回线性表的当前长度slist->len。该操作函数具体定义如下:

int SL_Length(SeqList*slist)

  • 判断线性表是否为空:若当前线性表是空表,则返回false,否则返回true.该操作函数具体定义如下:

BOOL SL_IsEmpty(SeqList*slist)

  • 判断线性表是否已满:若线性表达到最大长度,则返回true,否则返回false。该操作函数具体定义如下:

BOOL SL_IsFull(SeqList*slist)

  • 返回线性表第 i 个数据元素: 返回线性表的第 i 个数据元素 slist ->data[i] 。 该操作函数具体定义如下:

T SL_GetAt(SeqList* slist , int i)

  • 修改线性表第 i 个数据元素: 将线性表的第 i 个数据元素的值修改为 x 。 该操作函数具体定义如下:

void SL_SetAt(SeqList*slist, int i , T x)

  • 在线性表位置 i 插入数据元素 x : 将x 插入slist->data[i] 之前。若插入失败(i>slist-len 或 i <0时, 无法插入),返回false , 否则返回true。 该操作函数具体定义如下:

BOOL SL_InsAt(SeqList*slist , int i , T x)

  • 删除线性表位置 i 处 的数据元素: 删除线性表的 i 号数据元素。输入参数 i 范围应在 [0,slist -> len -1] 内,否则会产生不能预料的异常或错误。返回被删除的数据元素的值。该操作函数具体定义如下:

T SL_DelAt(SeqList* slist , int i)

  • 查找线性表中第一个值为x的数据元素的位置: 找到线性表中第一个值为x的数据元素的编号。返回值-1表示没有找到,返回值>=0表示该元素位置。该操作函数具体定义如下:

int SL_FindValue(SeqList* slist , T x)

  • 删除线性表中第一个值为x的数据元素: 删除第一个值为x的数据元素,返回该数据元素的编号。如果不存在值为x的数据元素,则返回-1. 该操作函数具体定义如下:

int SL_DelValue(SeqList*slist , T x)

  • 打印线性表: 打印整个线性表。该操作函数具体定义如下:

void SL_Print(SeqList*slist)

//顺序表操作实现

SeqList* SL_Create(int maxlen)
//创建一个顺序表。
//与SqLst_Free()配对。
{
    SeqList*slist=(SeqList*)malloc(sizeof(SeqList));
    slist->data = (T*)malloc (sizeof(T)*maxlen);
    slist -> max =maxlen;
    slist -> len=0;
    return slist;
}
void SL_Free(SeqList* slist)
//释放/删除 顺序表
//与SqLst_Create()配对
{
    free(slist -> data);
    free(slist);
}
void SL_MakeEmpty(SeqList* slist)
//置为空表
{
    slist -> len=0
}
int SL_Length(SeqList* slist)
//获取长度。
{
    return slist ->len;
}
bool SL_IsEmpty(SeqList* slist)
//判断顺序表是否为空
{
    return 0==slist ->len;
}
T SL_GetAt(SeqList* slist, int i)
//获取顺序表slist的第i号节点数据。
//返回第i号节点的值。
{
    if(i<0||i>=slist->len){
        printf("SL_GetAt():location error when reading elements of the slist!\n");
        SL_Free(slist);
        exit(0);
    }
    else
        return slist->data[i];
}
void SL_SetAt(SeqList* slist , int i ,T x)
//设置第i 号节点的值(对第i号结点的数据进行写)。
{
    if (i<0||i>=slist->len){
        printf("SL_SetAt():location error when setting elements of the slist!\n");
        SL_Free(slist);
        exit(0);
    }
    else
        slist->data[i]=x;
}

实现一个链接存储的线性表

#include
#include "LinkList.h"
// 1)
LinkList* LL_Create()
//创建一个链接存储的线性表,初始为空表,返回llist指针
{
    LinkList* llist=(LinkList*)malloc(sizeof(LinkList));
    llist->front=NULL;
    llist->rear=NULL;
    llist->pre=NULL;
    llist->curr=NULL;
    llist->position=0;
    llist->len=0;
    return llist;
}
// 2)
void LL_Free(LinkList* llsit)
//释放链表的结点,然后释放llist所指向的结构
{
    LinkNode* node=llist->front;
    LinkNode* nextnode;
    while (node){
        nextnode=node->next;
        free(node);
        node=nextnode;
    }
    free(llsit);
}
//3)
void LL_MakeEmpty(LinkList* llist)
//将当前线性表变为一个空表,因此需要释放所有结点
{
    LinkNode* node=llist->front;
    LinkNode* nextnode;
    while(node){
        nextnode=node->next;
        free(node);
        node=nextnode;
    }
    llist->front=NULL;
    llsit->rear=NULL;
    llist->pre=NULL;
    llist->curr=NULL;
    llist->position=0;
    llsit->len=0
}
int LL_Length(LinkList* llist)
//返回线性表的当前长度
{
    return llsit->len;
}
//5)
bool LL_IsEmpty(LinkList* llist)
//若当前线性表是空表,则返回true,否则返回False
{
    return llsit->==0;
}
//6)
bool LL_SetPosition(LinkList* llist, int i)
//设置线性表的当前位置为i号位置。
//设置成功,则返回ture,否则返回false(线性表为空,或i不在有效的返回)
//假设线性表当前长度len,那么i的有效范围为[0,len].
{
    int k;
    /*链表为空、或越界*/
    if(llist->len==0 || i<0 || i>llist->len ){
        printf("LL_SetPosition():position error");
        return false;
    }
    /*寻找对应结点*/
    llist ->curr=llist->front;
    llist->pre=NULL;
    llist->position=0;
    for (k=0;kposiontion++;
        llist->pre=llist->curr;
        llist->curr=(llist->curr)->next;
        }
        /*返回当前结点位置*/
        return true;
    }
}
//8)
bool LL_NextPosition(LinkList* llist)
//设置线性表的当前位置的下一个位置为当前位置。
//设置成功,则返回true,否则返回false(线性表为空,或当前位置为表尾)
{
    if(llist->position>=0 && lllsit->positionlen)
    /*若当前结点存在,则将其后设置为当前结点*/
    {
        llist->position++;
        llist->pre =llist->curr;
        llist->curr=llist->curr->next;
        return true;
    }
    else
    return false;
}
T LL_GetAt(LinkList* llist)
//返回线性表的当前位置的数据元素的值
{
    if(llist->curr==NULL)
    {
            printf("LL_GetAt():Empty list,or End of the List.\n");
            LL_Free(llist);
            exit(1);           
    }
    return llist->curr->data;
}
void LL_SetAt(LinkList* llist, T x)
//将线性表的当前位置的数据元素的值修改为x
{
    if(llist->curr==NULL)
    {
        printf("LL_SetAt():Empty list,or End of the List.\n";)
        LL_Free(llist);
        exit(1);
    }
    llist->curr->data=x;
}
//11)
bool LL_InsAt(LinkList* llsit,T x)
//在线性表的当前位置之前插入数据元素x.当前位置指针指向新数据元素结点。
{
    LinkNode *newNode=(LinkNode*)malloc(sizeof(LinkNode));
    if (newNode==NULL) return false;
    
    newNode->data=x;
    
    if (llist->len==0){
        //在空表中插入
        newNode->next=NULL;
        llist->front = llist->rear=newNode;
    }
    //当前位置为表头;
    else if (llist ->pre==NULL)
    {
        /*在表头结点处插入*/
        newNode->next=llist->front;
        llist->front=newNode;
    }
    else{
        /*在链表的中间位置或表尾后的位置插入*/
        newNode->next=llist->curr;
        llist->pre->next=newNode;
    }
    //插入在表尾后。
    if(llist->pre==llist->rear)
        llist->rear=newNode;
        /*增加链表的大小*/
        llsit->len++;
        /*新插入的结点为当前结点*/
        llist->curr=newNode;
        return true;    
}
//12)
bool LL_InsAfter(LinkList* llist , T x)
//在线性表的当前位置之后插入数据元素x。空表允许插入。当前位置指针将指向新结点。
//若插入失败,返回false,否则返回true.
{
    
}
//13)
bool LL_DelAt(LinkList* llist)
//删除线性表的当前位置的数据元素结点
//若删除失败(为空表,或当前位置为尾结点之后),则放回false,否则返回true
{
    LinkNode *oldNode;
    /*若表为空或已到表尾之后,则给出错误提示并返回*/
    if(llist->curr==NULL)
    {
        printf("LL_DelAt():delete a node that does not exist.\n");
        return false;
    }
    oldNode =llist->curr;
    /*删除的是表头结点*/
    if(llist->pre==NULL)
    {
        llist->front=oldNode->next;
    }
    /*删除的是表中或表尾结点*/
    else if (llsit->curr!NUll){
        llist->pre->next=oldNode->next;
    }
    if(oldNode==llist->rear){
        /*删除的是表尾结点,则修改表尾指针和当前结点位置值*/
        llist->rear=llist->pre;
    }
    /*后继节点作为新的当前结点*/
    llsit->curr=odlNode->next;
    /*释放原当前结点*/
    free*(oldNode);
    /*链表大小减*/
    llist->len --;
    return true;
}
//14)
bool LL_DelAfter(LinkList* llist)
//删除线性表的当前位置的那个数据元素
//若删除失败(为空表、或当前位置是表尾),则返回false,否则返回true
{
    LinkNode *oldNode;
    /*若表为空或已到表尾,则给出错误提示并返回*/
    if(llist->curr==NULL||llist->curr==llist->rear)
    {
        printf("LL_DelAfter():delete a node that does not exist.\n");
        return false;
    }
    /*保存被删除结点的指针并从链表中删除该节点*/
    oldNode = llist->curr->next;
    llist->curr->next=oldNode->next;
    
    if(oldNode==llsit->rear)
        /*删除的表尾结点*/
        llist->rear=llist->curr;
    /*释放别删除结点*/
    free(oldNode);
    llist->len--;
    return true;
    }
    //15)
    int LL_FindValue(LinkList* llist,T x)
    //找到线性表中第一个值为x的数据元素的编号。
    //返回值-1表示没有找到,返回值>=0表示标号。
    {
        LinkNode* p=llist->front;
        int idx=0;
        while(p!=NULL && p->data!=x){
            idx++;
            p=p->next;
        }
        if(idx>=llist->len)return -1;
        else return idx;
    }
    //16)
    int LL_DelValue(LinkList* llist, T x)
    //删除第一个值为x的数据元素,返回该数据元素的编号。如果不存在值为x的数据元素,则返回-1
    {
        int idx=LL_FindValue(llist,x);
        if(idx>0)return -1;
        LL_SetPosition(llsit,idx);
        LL_DelAt(llist);
        return idx;
    }
    //17))
    void LL_Print(LinkList* llist)
    //打印整个线性表
    {
        LinkNode* node=llist-front;
        while(node){
            printf("%d",node->data);
            node=node->next;
        }
        printf("\n");
    }

你可能感兴趣的:(数据结构)