线性表的定义:除了第一个结点和和最后一个结点,其他所有结点都有一个前驱结点和后继结点

线性表的分类:顺序表(顺序存储)和链表(链式存储)

顺序表

顺序存储和C中先天的数组差不多,在此不做叙述

优点

  • 支持随机存取,存取密度高
  • 大片连续空间分配不方便,改变容量不方便(定容)

特点:

  • 需要预留大片连续空间,若分配空间过小,则只会不方便扩展容量;若分配空间过大,则浪费内存资源

基本操作:数组这个东西,易,不做过多概述

链表

优点

  • 离散的小空间分配方便,改变容量方便
  • 不可随机存取,存储密度高

特点:

  • 只需要分配一个头结点(也可以不用头结点,只声明一个头指针),之后方便扩展

基本操作

#include <stdio.h>
#include <stdlib.h>
/*---------------------------------------定义单链表头结点-------------------------------------*/
typedef struct LNode {
    int data;       // 数据域
    struct LNode* next;     // 向后指针
}LNode, *LinkList;
/*---------------------------------------遍历一个单链表---------------------------------------*/
void Traverse(LinkList head) {
    while (head != NULL) {
        printf("%d ", head->data);
        head = head->next;
    }
}
/*---------------------------------------创建一个单链表----------------------------------------*/
LinkList CreateList() {
    LinkList head = (LinkList)malloc(sizeof(LNode));
    head->next = NULL;
    LinkList p = head;
    int data;
    printf("please input the number:\n");
    scanf("%d", &data);
    while (data != 9999) {
        LinkList node = (LinkList)malloc(sizeof(LNode));
        node->data = data;
        p->next = node;
        p = p->next;
        scanf("%d", &data);
    }
    p->next = NULL;
    // free(p);
    return head;
}
/*---------------------------------------插入一个结点-------------------------------------------*/
LinkList InsertList(LinkList head, int i, int data) {
    // head:头结点
    // i:要插入的位置
    // data:要插入的元素
    if (i < 1) return NULL;
    LinkList node = (LinkList)malloc(sizeof(LNode));
    node->data = data;
    int j = 0;
    LinkList p = head;
    while (p != NULL && j < i-1) {
        p = p->next;
        j++;
    }
    LinkList q = p->next;
    p->next = node;
    node->next = q;
    return head;
}
/*---------------------------------------删除一个结点------------------------------------------*/
LinkList DeleteList(LinkList head, int n) {
    // n:表示指定的位置
    LinkList p = head;
    int i = 0;
    while (p != NULL && i < n-1) {
        p = p->next;
        i++;
    }
    LinkList node = p->next->next;
    p->next = node;
    return head;
}
/*---------------------------------------查找一个结点的值---------------------------------------*/
int FindList(LinkList head, int data) {
    LinkList p = head;
    while (p != NULL && p->data != data) {
        p = p->next;
    }
    return p->data;
}
/*---------------------------------------定义双向链表头结点-------------------------------------*/
typedef struct DNode {
    int data;
    struct DNode* prior;
    struct DNode* next;
}DNode, *DLinkList;
/*---------------------------------------创建一个双向链表---------------------------------------*/
DLinkList CreateDList() {
    DLinkList head = (DLinkList)malloc(sizeof(DNode));
    head->next = NULL;
    head->prior = NULL;
    DLinkList p = head;
    int data;
    scanf("%d", &data);
    while (data != 9999) {
        DLinkList node = (DLinkList)malloc(sizeof(DNode));
        node->data = data;
        p->next = node;
        node->prior = p;
        p = p->next;
        scanf("%d", &data);
    }
    p->next = NULL;
    return head;
}
/*---------------------------------------定义循环链表头结点--------------------------------------*/
typedef struct CNode {
    // 此处只用循环单链表做演示
    int data;
    struct CNode* next;
}CNode, *CLinkList;
/*---------------------------------------创建一个循环单链表---------------------------------------*/
CLinkList CreateCList() {
    CLinkList head = (CLinkList)malloc(sizeof(CNode));
    // head->next = head;
    CLinkList p = head;
    int data;
    scanf("%d", &data);
    while (data != 9999) {
        CLinkList node = (CLinkList)malloc(sizeof(CNode));
        node->data = data;
        p->next = node;
        p = p->next;
        scanf("%d", &data);
    }
    p->next = head->next;
    return head;
}
// 主函数
int main()
{
    LinkList head = CreateList();       // 创建一个单链表
    LinkList head_f = head->next;
    Traverse(head_f);
    printf("\n");

    int data, n;        //插入一个元素
    printf("please input the number for inserting: "); 
    scanf("%d", &data);
    printf("please input the position for data: "); 
    scanf("%d", &n);
    LinkList head1 = InsertList(head, n, data);
    Traverse(head1->next);
    printf("\n");

    int n2;     // 删除一个元素
    printf("please input the number for delete: ");
    scanf("%d", &n2);
    LinkList head2 = DeleteList(head, n2);
    Traverse(head2->next);
    printf("\n");

    int data2;      // 查找一个元素
    printf("please input the number for finding: ");
    scanf("%d", &data2);
    int t = FindList(head, data2);
    printf("%d", t);
    printf("\n");

    DLinkList head3 = CreateDList();        // 创建一个双向链表
    DLinkList h = head3->next;
    while (h != NULL) {
        printf("%d ", h->data);
        h = h->next;
    }

    CLinkList head3 = CreateCList();
    CLinkList h = head3->next;
    int i = 0;
    while (i < 8) {
        printf("%d ", h->data);
        h = h->next;
        ++i;
    }

    printf("以上就是几乎所有的链表,这个几乎是因为我不喜欢静态链表");
    return 0;
}

比较

0:表示差,1:表示好

顺序表 链表
弹性-可扩容 0 1
增,删 0 1
查(按位) 1 0