【数据结构】线性表

知识目录
在这里插入图片描述

顺序表

  • 概念:用一组地址连续的存储单元依次存储线性表的数据元素,这种存储结构的线性表称为顺序表。

  • 特点:逻辑上相邻的数据元素,物理次序也是相邻的。

只要确定好了存储线性表的起始位置,线性表中任一数据元素都可以随机存取,所以线性表的顺序存储结构是一种随机存取的储存结构,因为高级语言中的数组类型也是有随机存取的特性,所以通常我们都使用数组来描述数据结构中的顺序储存结构,用动态分配的一维数组表示线性表。


定义以及初始化

#define MaxSize 50//顺序表的最大长度
typedef char ElemType;
typedef struct
{
    ElemType data[MaxSize];//顺序表的元素
    int length;//顺序表的当前长度
}SqList;

//初始化顺序表
void InitList(SqList *l){
    l->length = 0;//长度赋值为0
}

顺序表的插入操作

bool ListInsert(SqList *l,int i,ElemType e){//参数分别是:顺序表、插入的位置以及插入的元素
    //判断i的范围是否有效
    if (i<1||i>l->length+1)
        return false;
    //当前存储空间已满,不能插入
    if (l->length>=MaxSize)
        return false;
    //将第i个以及之后的元素后移
    for (int j = l->length; j >= i; j--)
    {
        l->data[j] = l->data[j-1];
    }
    l->data[i-1] = e;//赋值
    l->length = l->length + 1;//顺序表的长度+1
    return true;
}

删除操作

bool ListDelect(SqList *list,int i){
    //判断i的合法性
    if(i<1||i>list->length+1) return false;
    for(int j = i;j<=list->length;j++)//将第i后的元素前移
        list->data[j-1]=list->data[j];
    list->length--;//长度自减1
    return true;
}

按值查找,返回第一个位置

int locateElem(SqList list,ElemType e){//
    for (int j = 0; j < list.length; j++)
    {
        if (list.data[j]==e) return j+1;
    }
    return 0;//没有找到
}

按位查找

ElemType GetElem(SqList list,int i){
    return list.data[i-1];
}

按照顺序输出元素

void PrintList(SqList l){
    for (int i = 0; i < l.length; i++)
    {
         printf("%cn",l.data[i]);
    }
    printf("************************n");
}

链式存储

单链表

初始化

typedef char ElemType;

typedef struct LNode
{
    ElemType data;//data域
    struct LNode* next;//指针域
}LNode;

//初始化链表
void InitLNode(LNode *node){
    node = (LNode*)malloc(sizeof(LNode));//初始化新的node节点
    node->data = NULL;//给数值赋予初值
    node->next = NULL;//赋予下一个结点的指针
}

在这里插入图片描述

头插法

//头插法插入节点
bool LNodeHeadInsert(LNode* node,ElemType e){
    LNode* tempNode = (LNode*)malloc(sizeof(LNode));//开辟新的空间
    tempNode->data = e;//存储值
    tempNode->next = node->next;//指向第一个节点
    node->next = tempNode;//将头节点的下一个指针指向新的第一个节点
    return true;
}

尾插法

//尾插法插入
bool LNodeTailInsert(LNode* list,ElemType e){
    LNode* node = (LNode*)malloc(sizeof(LNode));//开辟空间,新建节点
    node->data = e;//data给到新建节点的数据域
    node->next = NULL;//新建节点指向NULL
    while(list->next)//寻找最后一个节点
    {
        list=list->next;
    }
    list->next=node;//最后一个节点指向新建节点
    return true;
}

删除
在这里插入图片描述

//删除
void LNodedelete(LNode* list,ElemType data)//删除
{
    LNode* pre=list;//保存头节点,它是current的前一个节点
    LNode* current=list->next;//保存第一个节点开始,从它开始遍历
    while(current)//遍历,可使用头节点data进行for循环遍历
    {
        if(current->data==data)//找到data
        {
            pre->next=current->next;//将前一个节点指向要要删除节点的下一个节点
            free(current);//释放要铲除节点的堆内存空间
            break;//退出循环
        }
        pre = current;//未找到data则往后继续遍历
        current = current->next;//未找到data则往后继续遍历
    }
}

双链表

初始化
在这里插入图片描述

typedef char ElemType;
//定义结点信息 
typedef struct DNode{
	struct DNode *prior;
	ElemType data;
	struct DNode *next;
}DNode; 

void InitDNode(DNode *node){
    node = (DNode*)malloc(sizeof(DNode));//开辟空间
    node->data = NULL;
    node->prior = NULL;
    node->next = NULL;
}

添加节点
在这里插入图片描述

//增加节点
void DNodeInsert(DNode *node,ElemType e){
    DNode *l = (DNode*)malloc(sizeof(DNode));//开辟空间
    l->data = e;
    l->next = node->next;
    node->next->prior = l;
    l->prior = node;
    node->next = l;
}

删除
在这里插入图片描述

//删除节点
void DNodeDelete(DNode *node,ElemType e){
    while (node->next)
    {
        if (node->data==e)
        {
           node->prior->next = node->next;
           node->next->prior = node->prior;
           break;
        }
        node = node->next;
    }
}