线性表

线性表的定义

  • 线性表就是零个或多个相同数据元素的有限序列

线性表特征(假设a为一张线性表)

  • 对非空表,a[0]是表头,无前驱
  • a[n-1]是表尾,无后继
  • 其它的每个元素a[i]有且仅有一个直接前驱a[i-1]和一个后继a[a+1]

线性表的基本运算(假设L为一张线性表)

  • 建立一个空表:Createlist(L)
  • 置空表:ClearList(L)
  • 判断表是否为空:IsEmpty(L)
    • 若为空返回True(1),否则返回False(0)
  • 求表长:Length(L)
  • 取表中的某个元素:GetList(L,i),即L[i],要求 0<=i<legth(L)-1
  • 定位运算:Locate(L,x) 确定元素x在表L的位置
    • 如果存在返回位置信息,如果不存在返回-1
  • 插入:Insert(L,x,i),将元素x插入到L表的第i个元素之前,且表长+1
  • 添加:Add(L,x),将元素x加入到L表中,且长+1
  • 删除:Delete(L,i),删除表L的第i个元素,且表长-1,要求 0<=i<legth(L)-1
  • 复合元素
    • 合并:Merge(L1,L2),将表L1和表L2合并为一张表,去重
    • 去重:Deduplication(L),将表L的元素去重

顺序存储

  • 顺序存储结构的特点
    • 逻辑上相邻的额元素a[i],a[i+1],其存储位置也是相邻的
    • 对数据元素a[i]的存取为随机存取或按地址存取
    • 存储密度高。存储密度D=(数据结构中元素所占存储空间)/(整个数据结构所占空间)
  • 顺序存储结构的不足
    • 对表的插入和删除等运算时间复杂度较高
#include  <stdio.h>
#include <stdlib.h>
// 线性表底层数组的长度
#define TableNum 6

// 线性表声明
typedef struct LinearTable {
    int List[TableNum]; // 数组长度
    int last; // 尾端标志位
} L;

// 初始化方法
L *initLinearTable() {
    L *LTable = NULL;
    if ((LTable = (L *) malloc(sizeof(L))) == NULL) {
        printf("Did not apply for enough memory space");
        return NULL;
    }
    LTable->last = -1;
    return LTable;
};

// 展现所有内容:
void Show(L *LTable) {
    printf("========start=========
");
    for (int i = 0; i < LTable->last + 1; ++i) {
        printf("index:%d -> value:%d 
", i, *(LTable->List + i));
    }
    printf("========end=========
");
}

// 置空表
void ClearList(L *LTable) {
    LTable->last = -1;
};

// 判断是否为空
int IsEmpty(L *LTable) {
    if (LTable->last == -1) {
        return 1;
    }
    return 0;
};

// 求数组长度
int Length(L *LTable) {
    return LTable->last + 1;
};

// 获取表中某个位置的元素
int GetElement(L *LTable, int i) {
    // 判断i的有效性 否则返回-1
    if (i >= 0 && i <= LTable->last) {
        return *(LTable->List + i);
    }
    return -1;
};

// 寻找表是否存在某元素
int LSearch(L *LTable, int element) {
    for (int i = 0; i <= LTable->last; ++i) {
        if (*(LTable->List + i) == element) {
            return i;
        }
    }
    return -1;
};

// 插入
void LInsert(L *LTable, int index, int element) {
    // 在数组有效范围内 index也在可取范围内
    if (index >= 0 && index <= TableNum - 1 && index - 1 <= LTable->last && LTable->last < TableNum - 1) {
        LTable->last++;
        for (int i = LTable->last; i > index; --i) {
            *(LTable->List + i) = *(LTable->List + i - 1);
        }
        *(LTable->List + index) = element;
    } else {
        printf("insert error list index:%d insert index:%d
", LTable->last, index);
    }
};

// 加入
void Add(L *LTable, int element) {
    // 在数组有效范围内
    if (LTable->last < TableNum - 1) {
        LTable->last++;
        *(LTable->List + LTable->last) = element;
    } else {
        printf("Add Error length > %d", TableNum);
    }

}

// 删除
void LDelete(L *LTable, int index) {
    if (index >= 0 && index <= LTable->last) {
        LTable->last--;
        for (int i = index; i <= LTable->last; ++i) {
            *(LTable->List + i) = *(LTable->List + i + 1);
        }
    } else {
        printf("Delete error: index:%d last:%d
", index, LTable->last);
    }
};

// 清除该数据结构
void Del(L *LTable) {
    free(LTable);
}

int main(int argc, const char *argv[]) {
    printf("======test=======
");
    L *now;
    int i;
    // 新建
    now = initLinearTable();
    // 判断是否为空
    i = IsEmpty(now);
    printf("是否为空: %d
", i);
    // 判断长度
    i = Length(now);
    printf("长度为: %d
", i);
    // 添加数据
    Add(now, 1);
    Add(now, 2);
    // 展示所有
    Show(now);
    // 判断是否为空
    i = IsEmpty(now);
    printf("是否为空: %d
", i);
    // 判断长度
    i = Length(now);
    printf("长度为: %d
", i);
    // 插入
    LInsert(now, 0, 3);
    // show
    Show(now);
    LInsert(now, 3, 4);
    // show
    Show(now);
    // delete
    LDelete(now, 3);
    // show
    Show(now);
    //    // 清空
    //    ClearList(now);
    //    // show
    //    Show(now);
    // 按位置获取元素
    // 释放
    free(now);
    now = NULL;
    // 后面报错
    i = GetElement(now, 2);
    printf("元素为: %d
", i);
    // 查找是否有元素
    i = LSearch(now, 5);
    printf("索引为: %d
", i);
    i = Length(now);
    printf("长度为: %d
", i);
}

链式存储

#include  <stdio.h>
#include <stdlib.h>

// 链表结构
typedef struct LinkList {
    int data;
    struct LinkList *next;
} LS;


// 初始化 返回哑结点
LS *initLinkList() {
    LS *head = NULL;
    if ((head = (LS *) malloc(sizeof(LS))) == NULL) {
        printf("Did not apply for enough memory space
");
        return NULL;
    }
    head->next == NULL;
    return head;
}

// 封装函数 增加单链
LS *newLinkList(int i) {
    LS *head = NULL;
    if ((head = (LS *) malloc(sizeof(LS))) == NULL) {
        printf("Did not apply for enough memory space
");
        return NULL;
    }
    head->data = i;
    head->next == NULL;
    return head;
}

// show 展示函数
void Show(LS *link) {
    printf("========start=========
");
    link = link->next;
    while (link != NULL) {
        printf("%d
", link->data);
        link = link->next;
    }
    printf("========end=========
");

}

// 头部插入
void HeadAdd(LS *link, int i) {
    LS *member = NULL;
    LS *mid = NULL;
    member = newLinkList(i);
    if (member == NULL) {
        puts("Head Add error: No apply memory
");
        return;
    }
    mid = link->next;
    link->next = member;
    member->next = mid;
}

// 尾部插入
void TailAdd(LS *link, int i) {
    if (link == NULL) {
        puts("link is empty");
        return;
    }
    LS *member = NULL;
    member = newLinkList(i);
    if (member == NULL) {
        puts("Head Add error: No apply memory
");
        return;
    }
    while (link->next != NULL) {
        link = link->next;
    }
    link->next = member;
}

// 指定插入 index 起止为0
void AssignAdd(LS *link, int index, int i) {
    if (index < 0) {
        printf("index:%d < 0
", index);
        return;
    }
    // 特殊处理 插在首尾
    if (index == 0) {
        LS *mid = NULL;
        LS *member = NULL;
        member = newLinkList(i);
        if (member == NULL) {
            puts("AssignAdd error: No apply memory
");
            return;
        }
        mid = link->next;
        link->next = member;
        member->next = mid;
        return;
    }
    while (link != NULL && index > 0) {
        index--;
        link = link->next;
    }
    if (link != NULL) {
        LS *mid = NULL;
        LS *member = NULL;
        member = newLinkList(i);
        if (member == NULL) {
            puts("AssignAdd error: No apply memory
");
            return;
        }
        mid = link->next;
        link->next = member;
        member->next = mid;
        return;
    } else {
        puts("index over link length
");
    }
}

// 指定删除 index 起止为0
void DeleteIndex(LS *link, int index) {
    if (index < 0) {
        printf("index:%d<0
", index);
        return;
    }
    while (link != NULL && --index >= 0) {
        link = link->next;
    }
    if (link && link->next) {
        if (link->next && link->next->next) {
            link->next = link->next->next;
        } else {
            link->next = NULL;
        }
    } else {
        printf("index over length
");
    }
}

// 指定删除 data
void DeleteData(LS *link, int data) {
    LS *Previous;
    Previous = link;
    link = link->next;
    while (link) {
        if (link->data == data) {
            Previous->next = link->next;
            return;
        }
        Previous = Previous->next;
        link = link->next;
    }
    printf("data is exist
");
}

// 寻找 根据index寻找
int SearchIndex(LS *link, int index) {
    if (index < 0) {
        printf("index:%d<0
", index);
        return -1;
    }
    while (link != NULL && index != -1) {
        link = link->next;
        index--;
    }
    if (link != NULL) {
        return link->data;
    }
    return -1;
}

// 寻找 根据value寻找
int SearchData(LS *link, int data) {
    int i = 0;
    link = link->next;
    while (link != NULL) {
        if (link->data == data) {
            return i;
        }
        link = link->next;
        i++;
    }
    return -1;
}

// 排序
void sortLink(LS *link) {
    LS *other, *nowOther, *head;
    other = link->next;
    link->next = NULL;
    while (other) {
        nowOther = other;
        other = other->next;
        head = link;
        while (head->next && head->next->data < nowOther->data) {
            head = head->next;
        }
        nowOther->next = head->next;
        head->next = nowOther;
    }

}

// 释放
void Del(LS *link) {
    while (link != NULL) {
        free(link);
        link = link->next;
    }
}

int main() {
    // 初始化
    LS *head = NULL;
    int i = 0;
    // 初始化
    head = initLinkList();
    Show(head);
    // 尾插
    TailAdd(head, 3);
    TailAdd(head, 4);
    // 头插
    HeadAdd(head, 1);
    HeadAdd(head, 2);
    TailAdd(head, 5);
    TailAdd(head, 6);
    Show(head);
//     指定插入
    AssignAdd(head, 3, 7);
    Show(head);
    // 寻找
    i = SearchIndex(head, 6);
    printf("index:%d
", i);
    // 通过元素寻找
    i = SearchData(head, 9);
    printf("index:%d
", i);
    //     排序
    sortLink(head);
    Show(head);
    DeleteIndex(head, 6);
    Show(head);
    // 指定data删除
    DeleteData(head,2);
    Show(head);
    Del(head);
}

栈是限制在一端进行插入操作和删除操作的线性表(俗称堆栈),允许进行操作的一端称为"栈顶",另一固定端称为"栈底",当栈中没有元素时称为"空栈"。特点,后进先出

基本运算

  • 创建空栈
  • 清空栈
  • 判断栈是否为空
  • 判断栈是否为慢
  • 元素进栈
  • 元素出栈
  • 获取栈顶
#include  <stdio.h>
#include <stdlib.h>


typedef struct stack {
    int *stackList; // 指向栈的数组
    int stackLen; // 栈的长度
    int top; // 目前头的位置
} stacks;

// 初始化空栈
stacks *initStack(int stackLen) {
    if (stackLen <= 0) {
        puts("stackLen <= 0");
        return NULL;
    }
    stacks *newStack = NULL;
    int *list;
    // 第一次申请内存
    if ((newStack = (stacks *) (malloc(sizeof(stacks)))) == NULL) {
        puts("No memory at newStack");
        return NULL;
    }
    if ((list = (int *) (malloc(sizeof(int[stackLen - 1])))) == NULL) {
        // 释放第一次申请的内存
        free(newStack);
        puts("No memory at list");
        return NULL;
    }
    newStack->top = -1;
    newStack->stackLen = stackLen;
    newStack->stackList = list;
    return newStack;
}

// show
void show(stacks *stack) {
    printf("========start=========
");
    for (int i = 0; i <= stack->top; ++i) {
        printf("%d
", *(stack->stackList + i));
    }
    printf("========end=========
");
}


// 判断是否为空栈
int isStackEmpty(stacks *stack) {
    if (!stack) {
        puts("stack no find");
        return -1;
    }
    if (stack->top == -1) {
        return 1;
    }
    return 0;
}

// 判断是否为满栈
int isStackFull(stacks *stack) {
    if (!stack) {
        puts("stack no find");
        return -1;
    }
    if (stack->top == stack->stackLen - 1) {
        return 1;
    }
    return 0;
}

// 入栈
void addStack(stacks *stack, int num) {
    int i = 0;
    // 先判断是否栈满
    i = isStackFull(stack);
    if (i == 1 || i == -1) {
        // 满或者为空
        puts("stack is full or no find");
        return;
    }
    *(stack->stackList + (++stack->top)) = num;
}

// 出栈
int outStack(stacks *stack) {
    int i = 0;
    // 判断是否为空
    i = isStackEmpty(stack);
    if (i == 1 || i == -1) {
        // 满或者为空
        puts("stack is empty or no find");
        return -1;
    }
    return *(stack->stackList + (stack->top--));
}

// 查看栈顶
int topStack(stacks *stack) {
    int i = 0;
    i = isStackEmpty(stack);
    if (i == 1 || i == -1) {
        // 满或者为空
        puts("stack is empty or no find");
        return -1;
    }
    return *(stack->stackList + (stack->top));
}

// 销毁
void Del(stacks *stack) {
    free(stack->stackList);
    stack->stackList = NULL;
    free(stack);
}


int main() {
    int i = 0;
    // 创建
    stacks *stack = NULL;
    stack = initStack(5);
    show(stack);
    addStack(stack, 5);
    addStack(stack, 3);
    addStack(stack, 9);
     i = topStack(stack);
    printf("顶 %d
", i);
    addStack(stack, 4);
    show(stack);
    i = outStack(stack);
    printf("出栈 %d
", i);
    i = outStack(stack);
    printf("出栈 %d
", i);
    show(stack);
    // 查看顶
    i = topStack(stack);
    printf("顶 %d
", i);
    show(stack);
    Del(stack);
}

对列

  特殊的线性表,先进先出(FIFO)

基本运算

  • 创建空对列
  • 清空对列
  • 判断对列是否为空
  • 判断对列是否为慢
  • 元素进对列
  • 元素出对列
#include  <stdio.h>
#include <stdlib.h>

typedef struct alignment {
    int *alignmentList; // 指向对列的数组
    int alignmentLen; // 栈的长度
    int top; // 目前头的位置
    int tail; // 指向尾的位置
} alignments;

// 初始化方法
alignments *initAlignment(int alignmentLen) {
    if (alignmentLen <= 0) {
        puts("alignmentLen <= 0");
        return NULL;
    }
    alignments *newAlignment = NULL;
    int *list = NULL;
    // 第一次申请内存
    if ((newAlignment = (alignments *) malloc(sizeof(alignments))) == NULL) {
        puts("No memory at newAlignment");
        return NULL;
    }
    // 第二次申请内存
    if ((list = (int *) malloc(sizeof(int[alignmentLen]))) == NULL) {
        // 释放第一次申请的内存
        free(newAlignment);
        puts("No memory at list");
        return NULL;
    }
    newAlignment->alignmentLen = alignmentLen;
    newAlignment->alignmentList = list;
    newAlignment->top = 0;
    newAlignment->tail = alignmentLen - 1;
    return newAlignment;
}

// show
void show(alignments *alignment) {
    int top, tail;
    top = alignment->top;
    tail = alignment->tail;
    printf("========start=========
");
    while ((tail + 1) % alignment->alignmentLen != top) {
        tail = (tail + 1) % alignment->alignmentLen;
        printf("%d
", *(alignment->alignmentList + tail));
    }
    printf("========end=========
");
}

// 判断是否为空列
int isStackEmpty(alignments *alignment) {
    if (!alignment) {
        puts("alignment no find");
        return -1;
    }
    if ((alignment->tail + 1) % alignment->alignmentLen == alignment->top) {
        return 1;
    }
    return 0;
}

// 判断是否为满列
int isStackFull(alignments *alignment) {
    if (!alignment) {
        puts("alignment no find");
        return -1;
    }
    if (alignment->top == alignment->tail) {
        return 1;
    }
    return 0;
}

// 入列
void addAlignment(alignments *alignment, int num) {
    int i = 0;
    // 先判断是否栈满
    i = isStackFull(alignment);
    if (i == 1 || i == -1) {
        // 满或者为空
        puts("alignment is full or no find");
        return;
    }
    *(alignment->alignmentList + alignment->top) = num;
    alignment->top = (++alignment->top) % alignment->alignmentLen;
}

// 出列
int outAlignment(alignments *alignment) {
    int i = 0;
    // 判断是否为空
    i = isStackEmpty(alignment);
    if (i == 1 || i == -1) {
        // 满或者为空
        puts("alignment is empty or no find");
        return -1;
    }
    alignment->tail = (alignment->tail + 1) % alignment->alignmentLen;
    return *(alignment->alignmentList + alignment->tail);
}

// 销毁
void Del(alignments *alignment) {
    free(alignment->alignmentList);
    alignment->alignmentList = NULL;
    free(alignment);
}


int main() {
    int i = 0;
    // 创建
    alignments *alignment = NULL;
    alignment = initAlignment(5);
    show(alignment);
    i = isStackEmpty(alignment);
    printf("是否为空:%d
", i);
    i = isStackFull(alignment);
    printf("是否为满:%d
", i);
    // 加入
    addAlignment(alignment, 5);
    addAlignment(alignment, 3);
    addAlignment(alignment, 6);
    addAlignment(alignment, 9);
    addAlignment(alignment, 7);
    i = isStackEmpty(alignment);
    printf("是否为空:%d
", i);
    i = isStackFull(alignment);
    printf("是否为满:%d
", i);
    show(alignment);
    i = outAlignment(alignment);
    printf("出列:%d
", i);
    addAlignment(alignment, 1);
    addAlignment(alignment, 2);
    show(alignment);
    i = isStackEmpty(alignment);
    printf("是否为空:%d
", i);
    i = isStackFull(alignment);
    printf("是否为满:%d
", i);
    i = outAlignment(alignment);
    printf("出列:%d
", i);
    i = outAlignment(alignment);
    printf("出列:%d
", i);
    i = outAlignment(alignment);
    printf("出列:%d
", i);
    i = outAlignment(alignment);
    printf("出列:%d
", i);
    i = outAlignment(alignment);
    printf("出列:%d
", i);
    i = isStackEmpty(alignment);
    printf("是否为空:%d
", i);
    i = isStackFull(alignment);
    printf("是否为满:%d
", i);
    show(alignment);
    // 销毁
    Del(alignment);
}
Songzhibin
原文地址:https://www.cnblogs.com/binHome/p/12818224.html