线性表

Posted sanweizuiji

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线性表相关的知识,希望对你有一定的参考价值。

1 线性表

1.1 定义

1.2 逻辑结构

1.3 基本操作

创销、增删改查

2 用顺序存储的方式来实现线性表(顺序表)

2.1 定义

2.2 特点

随机访问,能在O(1)时间内找到第i个元素

存储密度高

拓展容量不方便

插入、删除数据元素不方便

2.3 基本操作的实现

#include<cstdio>
#include<cstring>

#define MaxSize 10
using namespace std;

// 顺序表数据结构
typedef struct 
    // 顺序表元素
    int data[MaxSize];
    // 顺序表当前长度
    int length;
 SqList;

// 初始化顺序表函数,构造一个空的顺序表
void InitList(SqList &L) 
    // memset: 将某一块内存中的内容全部设置为指定的值
    memset(L.data, 0, sizeof(L));
    L.length = 0;


// 在表 L 中的位置 i 上插入指定元素 e
void ListInsert(SqList &L, int i, int e) 
    if (i < 1 || i > L.length + 1) 
        printf("位置 i 无效\\n");
     else if (L.length >= MaxSize) 
        printf("当前存储空间已满\\n");
     else 
        // 位置 i 及之后元素后移
        for (int j = L.length; j >= i; j--) 
            L.data[j] = L.data[j - 1];
        
        L.data[i - 1] = e;
        L.length++;
    


// 删除函数 删除位置 i 的元素 i 之后的元素依次前移
void ListDelete(SqList &L, int i) 
    if (i < 1 || i > L.length) 
        printf("位置 i 无效\\n");
     else 
        // 位置i之后元素依次前移覆盖
        for (int j = i; j <= L.length - 1; j++) 
            L.data[j - 1] = L.data[j];
        
        L.length--;
    


// 按位置从小到大查找第一个值等于 e 的元素 并返回位置
int LocateElem(SqList L, int e) 
    for (int i = 0; i < L.length; i++) 
        if (L.data[i] == e) 
            return i + 1;
        
    
    return -1;


// 输出顺序表中的所有元素
void PrintList(SqList L) 
    printf("打印顺序表 -----\\n");
    if (L.length == 0) 
        printf("该顺序表为空\\n");
    
    for (int i = 0; i < L.length; i++) 
        printf("data[%d] = %d\\n", i, L.data[i]);
    
    printf("--------------\\n");


int main() 
    SqList L;

    printf("初始化一个顺序表\\n");
    InitList(L);
    PrintList(L);

    printf("向位置 1 插入一个元素 123123\\n");
    ListInsert(L, 1, 123123);
    PrintList(L);

    printf("向位置 1 插入一个元素 345345\\n");
    ListInsert(L, 1, 345345);
    PrintList(L);

    printf("获取元素 123123 的位置\\n");
    printf("%d\\n", LocateElem(L, 123123));

    printf("删除位置 1 上的元素\\n");
    ListDelete(L, 1);
    PrintList(L);

    printf("获取元素 123123 的位置\\n");
    printf("%d\\n", LocateElem(L, 123123));

    return 0;

例 线性表的顺序存储结构是一种(随机存取的存储结构)

3 用链式存储的方式来实现线性表(链式表)

3.1 单向链表

#include <cstdio>
#include <cstdlib>

struct linkedListNode 
    int data;
    struct linkedListNode *next;
;
// 将 struct linkedListNode 简化为 linkedListNode
typedef struct linkedListNode linkedListNode;

// 初始化链表
// 如果不带头节点的话,进行第一个节点的插入或删除操作时需要特殊处理(要单独修改头指针的指向),比较繁琐
void initLink(linkedListNode *&L) 
    // 创建一个头结点
    L = (linkedListNode *) malloc(sizeof(linkedListNode));
    L->next = NULL;


// 获取指向第 index 个结点的指针
linkedListNode *getLinkedListNode(linkedListNode *l, int index) 
    if (index < 0) 

        return NULL;
     else 
        linkedListNode *temp = l;
        // nodeNum 表示节点个数,从第 0 个节点开始(第 0 个节点就是头节点)
        for (int nodeNum = 0; temp != NULL && nodeNum < index; nodeNum++) 
            temp = temp->next;
        
        return temp;
    


// 在第 index 个结点的位置上插入一个结点
void listInsert(linkedListNode *&l, int index, int data) 
    if (index < 1) 
        printf("插入位置的区间应为 [1,n]\\n");
     else 
        // 获取指向第 index-1 个结点的指针
        linkedListNode *temp = getLinkedListNode(l, index - 1);
        if (temp == NULL) 
            printf("第 %d 个节点不存在,所以无法后插\\n", index - 1);
         else 
            // 创建插入结点 c
            linkedListNode *c = (linkedListNode *) malloc(sizeof(linkedListNode));
            c->data = data;
            // 向链表中插入结点
            c->next = temp->next;
            temp->next = c;
        
    


// 删除结点
void listDelete(linkedListNode *l, int index) 
    if (index < 1) 
        printf("删除元素的位置的区间应为 [1,n]\\n");
     else 
        // 获取指向第 index-1 个结点的指针
        linkedListNode *temp = getLinkedListNode(l, index - 1);
        if (temp == NULL) 
            printf("第 %d 个节点不存在\\n", index - 1);
         else if (temp->next == NULL) 
            printf("第 %d 个节点不存在\\n", index);
         else 
            linkedListNode *delNode = temp->next;
            temp->next = delNode->next;
            // 手动释放该结点,防止内存泄漏
            free(delNode);
        
    


void printList(linkedListNode *L) 
    printf("\\n");
    printf("打印链表 -----\\n");
    // 定义 temp 指针指向头结点
    linkedListNode *temp = L;
    // 只要 temp 指针指向的结点的 next 不为空,就执行输出语句,否则结束函数并输出提示语
    if (temp->next) 
        while (temp->next) 
            temp = temp->next;
            printf("%d ", temp->data);
        
        printf("\\n");
     else 
        printf("该链表为空\\n");
    
    printf("------------\\n");
    printf("\\n");


int main() 
    printf("初始化链表\\n");
    linkedListNode *pLinkedListNode;
    initLink(pLinkedListNode);
    printList(pLinkedListNode);

    printf("在位置 1 插入一个元素 123123,在位置 2 插入一个元素 345345\\n");
    listInsert(pLinkedListNode, 1, 123123);
    listInsert(pLinkedListNode, 2, 345345);
    printList(pLinkedListNode);

    printf("删除位置 1 的元素\\n");
    listDelete(pLinkedListNode, 1);
    printList(pLinkedListNode);

    return 0;

3.2 双向链表

#include <cstdio>
#include <cstdlib>

struct DNode 
    int data;
    struct DNode *prior;
    struct DNode *next;
;

typedef struct DNode DNode;

void initDLinkList(DNode *&l) 
    l = (DNode *) malloc(sizeof(DNode));
    if (l == NULL) 
        printf("申请内存不足失败");
     else 
        l->prior = NULL;
        l->next = NULL;
    


// 获取指向第 index 个结点的指针
DNode *getDNode(DNode *l, int index) 
    if (index < 0) 
        printf("获取结点的位置区间应为 [0,n]\\n");
        return NULL;
     else 
        DNode *temp = l;
        // nodeNum 表示节点个数,从第 0 个节点开始(第 0 个节点就是头节点)
        for (int nodeNum = 0; temp != NULL && nodeNum < index; nodeNum++) 
            temp = temp->next;
        
        return temp;
    


DNode *createDNode(int data) 
    DNode *newNode = (DNode *) malloc(sizeof(DNode));
    if (!newNode) 
        printf("分配空间失败,请检查内存\\n");
        return NULL;
    
    //[2]初始化新节点
    newNode->data = data;
    newNode->next = NULL;
    newNode->prior = NULL;
    //[3]返回节点地址
    return newNode;


// 在第 index 个结点的位置上插入一个结点
void dListInsert(DNode *l, int index, int data) 
    if (index < 1) 
        printf("位置的区间应为 [1,n]\\n");
     else 
        DNode *s = createDNode(data);
        if (s == NULL) 
            printf("根据输入数据新建的结点为空");
         else 
            // 获取指向第 index-1 个结点的指针
            DNode *temp = getDNode(l, index - 1);
            if (temp == NULL) 
                printf("第 %d 个节点不存在,所以无法后插\\n", index - 1);
             else 
                s->next = temp->next;
                if (temp->next != NULL) 
                    temp->next->prior = s;
                
                s->prior = temp;
                temp->next = s;
            
        
    


// 删除结点
void dLisDelete(DNode *l, int index) 
    if (index < 1) 
        printf("删除元素的位置的区间应为 [1,n]\\\\n");
     else 
        // 找到待删除元素的前一位 *temp
        DNode *temp = getDNode(l, index - 1);
        if (temp == NULL) 
            printf("第 %d 个节点不存在,所以无法删除它后边的结点\\n", index - 1);
         else 
            DNode *nodeToBeDeleted = temp->next;
            if (nodeToBeDeleted == NULL) 
                printf("第 %d 个节点不存在\\n", index);
             else 
                temp->next = nodeToBeDeleted->next;
                // 若 *nodeToBeDeleted 不是最后一位元素
                if (nodeToBeDeleted->next != NULL) 
                    nodeToBeDeleted->next->prior = temp;
                
                free(nodeToBeDeleted);
            
        
    


void printList(DNode *L) 
    printf("\\n");
    printf("打印链表 -----\\n");
    // 定义 temp 指针指向头结点
    DNode *temp = L;
    // 只要 temp 指针指向的结点的 next 不为空,就执行输出语句,否则结束函数并输出提示语
    if (temp->next) 
        while (temp->next) 
            temp = temp->next;
            printf("%d ", temp->data);
        
        printf("\\n");
     else 
        printf("该链表为空\\n");
    
    printf("------------\\n");
    printf("\\n");


int main() 
    DNode *L;
    initDLinkList(L);

    dListInsert(L, 1, 123123);
    dListInsert(L, 1, 345345);
    dListInsert(L, 3, 575685);
    printList(L);

    dLisDelete(L, 3);
    dLisDelete(L, 1);
    printList(L);
    return 0;

3.3 单向循环链表

3.4 双向循环链表

3.5 静态链表

分配一整片连续的内存空间,各个结点集中安置

以上是关于线性表的主要内容,如果未能解决你的问题,请参考以下文章

线性表—顺序表

线性表的概念与实现

线性表

数据结构-线性表

数据结构-线性表

线性表