Postgraduate entrance examination | Data structure [Chapter 2] Linear table

Postgraduate entrance examination | Data structure [Chapter 2] Linear table

I. Linear table

  1. definition:A linear table is n ( n ≥ 0 ) n\ (n\geq0) of the same data typen (n0 ) a finite array of data elements, wherennn is the table length
  2. Basic operation:
    InitList(&L): 初始化表. 构造一个空的线性表L, 分配内存空间
    DestroyList(&L): 销毁表并释放线性表L所占用的内存空间.
    ---
    ListInsert(&L, i, e): 插入操作. 在表L中第i个位置插入指定元素e.
    ListDelete(&L, i, &e): 删除操作. 删除表L中第i个元素, 并用参数e返回删除元素的值.
    ---
    LocateElem(L, e): 按值查找
    GetElem(L, i): 按位查找, 获取表L中第i个位置的元素的值
    ---
    Length(L): 求表长
    PrintList(L): 从前到后输出线性表L中所有元素
    Empty(L): 判空操作
    

II. Sequence table

a. Definition

  1. definition:Use sequential storage to realize sequential storage of linear tables. Store logically adjacent elements in storage units that are also physically adjacent.
  2. Static allocation:
    #include <stdio.h>
    #define MaxSize 10
    typedef struct {
          
          
    	int data[MaxSize];
    	int length;
    }SqList;
    
    void InitList(SqList &L) {
          
          
    	for(int i=0; i<MaxSize; i++)
    		L.data[i] = 0;
    	L.Length = 0;
    }
    
    int main() {
          
          
    	SqList L;
    	InitList(L);
    	...
    	return 0;
    }
    
  3. Dynamic allocation:
    // 定义动态顺序表
    typedef struct {
          
          
        int *data;
        int maxSize;
        int lenght;
    }seqDList;
    // 初始化动态顺序表
    void initDList(seqDList &L) {
          
          
        L.data = (int *)malloc(MaxSize*sizeof(int));
        L.maxSize = dftMaxSize;
        L.lenght = 0;
    }
    // 扩充动态顺序表
    void increaseDList(seqDList &L, int len) {
          
          
        int* p = L.data;
        L.data = (int *)malloc((L.maxSize+len)*sizeof(int));
        for (int i=0; i<L.lenght; i++) {
          
          
            L.data[i] = p[i];
        }
        L.maxSize = L.maxSize + len;
        free(p);
    }
    
  4. Features:
    1. Random access, time complexity O ( 1 ) O(1)O(1)
    2. High storage density, each node only stores data elements
    3. Inconvenient to expand
    4. Insertion and deletion operations are inconvenient, and a large number of elements need to be moved

b. Insertion and deletion

  1. insert:
    // 在第i位插入元素
    bool insertSList(seqSList &L, int i, int e) {
          
          
        if (i<1 || i>L.length+1)
            return false;
        if (L.length >= dftMaxSize)
            return false;
        for (int j=L.length; j >= i; j--)
            L.data[j] = L.data[j-1];
        L.data[i-1] = e;
        L.length++;
        return true;
    }
    
    Time Complexity: Best O ( 1 ) O(1)O ( 1 ) , maximumO ( n ) O(n)O ( n ) , averageO ( n ) O(n)O ( n )
  2. delete:
    // 删除第i位元素
    bool deleteSList(seqSList &L, int i, int &e) {
          
          
        if (i<1 || i>L.length)
            return false;
        e = L.data[i-1];
        for (int j=i; j<L.length; j++)
            L.data[j-1] = L.data[j];
        return true;
    }
    
    Time Complexity: Best O ( 1 ) O(1)O ( 1 ) , maximumO ( n ) O(n)O ( n ) , averageO ( n ) O(n)O ( n )

c. Find

  1. Bitwise lookup:
    // 按位查找
    int GetElem(seqSList &L, int i) {
          
          
        return L.data[i-1]
    }
    
    Time complexity O ( 1 ) O(1)O(1)
  2. Find by value:
    // 按值查找
    int LocateElem(seqSList &L, int e) {
          
          
        for (int i=0; i<L.length; i++)
            if (L.data[i]==e)
                return i+1;
        return 0;
    }
    
    Time Complexity: Best O ( 1 ) O(1)O ( 1 ) , maximumO ( n ) O(n)O ( n ) , averageO ( n ) O(n)O ( n )

III. Singly linked list

a. Definition

A linear list stored in a linked storage structure is called a singly linked list.
insert image description here

  1. Establishment and initialization of the lead node
    typedef struct LNode {
          
          
        int data;
        struct LNode *next;
    }LNode, *linkList;
    
    // 带头结点初始化和判空
    bool initList_h(linkList &L) {
          
          
        if (L==NULL)
            return false;
        L->next = NULL;
        return true;
    }
    bool empty_h(linkList &L) {
          
          
        if (L->next == NULL)
            return true;
        else
            return false;
    }
    
  2. Creation and initialization of unleaded nodes
    // 不带头节点初始化和判空
    bool initList(linkList &L) {
          
          
        L->next = NULL;
        return true;
    }
    bool empty(linkList L) {
          
          
        return L==NULL;
    }
    

b. to insert

  1. Bitwise insertion of leading node:Time complexity O ( n ) O(n)O ( n )
    // 带头结点按位序插入
    bool listInsert(linkList &L, int i, int e) {
          
          
        if (i < 1)          // i 代表的是第i个结点
            return false;
        LNode *p;
        int j = 0;
        p = L;
        while (p!=NULL && j<i-1) {
          
            // 令p指到第i-1个结点位置采用后插法
            p = p->next;
            j++;
        }
        if (p == NULL)
            return false;
        LNode *s = (LNode *)malloc(sizeof(LNode));
        s->data = e;
        s->next = p->next;
        p->next = s;
        return true;
    }
    
  2. bitwise insertion without a head node: time complexity O ( n ) O(n)O ( n )
    // 不带头节点按位序插入
    bool listInsert(linkList &L, int i, int e) {
          
          
        if (i < 1)
            return false;
        if (i == 1) {
          
          
            LNode *s = (LNode *)malloc(sizeof(LNode));
            s->data = e;
            s->next = L;
            L = s;
            return true; 
        }
        LNode *p = L;
        int j = 1;
        while (p!=NULL && j < i-1) {
          
          
            p = p->next;
            j++;
        }
        if (p == NULL)
            return false;
        LNode *s = (LNode *)malloc(sizeof(LNode));
        s->data = e;
        s->next = p->next;
        p->next = s;
        return true;
    }
    
  3. The post-insertion operation of the specified node:Time complexity O ( 1 ) O(1)O(1)
    // 指定节点的后插操作
    bool inserNextNode(LNode *p, int e) {
          
          
        if (p == NULL)
            return false;
        LNode *s = (LNode *)malloc(sizeof(LNode));
        if (s == NULL)
            return false;
        s->data = e;
        s->next = p->next;
        p->next = s;
        return true;
    }
    
  4. The forward insertion operation of the specified node:Time complexity bit O ( 1 ) O(1)The O ( 1 ) version
    is essentially a back-interpolation method, but it just inserts a new node intoppAfter p , then make the data of the new node equal to ppThe data of p , whileppThe data of p is equal to the new data, so as to achieve a "forward interpolation" effect.
    // 指定结点的前插操作 O(1)
    bool inserPriorNode(LNode *p, int e) {
          
          
        if (p == NULL)
            return false;
        LNode *s = (LNode *)malloc(sizeof(LNode));
        if (s == NULL)
            return false;
        s->next = p->next;
        p->next = s;
        s->data = p->data;
        p->data = e;
        return true;
    }
    

c. delete

  1. The leading node is deleted in bit order:Average time complexity O ( n ) O(n)O ( n )
    // 带头节点按位序删除
    bool listDelete_h(linkList &L, int i, int &e) {
          
          
        if (i < 1)
            return false;
        LNode* p = L;
        int j = 0;
        while (p!=NULL && j<i-1) {
          
            // 将p指到第i-1个节点
            p = p->next;
            j++;
        }
        if (p == NULL || p->next == NULL)   // 表示第i-1或第i个节点不存在
            return false;
        LNode *q = p->next;
        e = q->data;
        p->next = q->next;
        free(q);
        return true;
    }
    
  2. Specified node deletion:Time complexity O ( 1 ) O(1)O ( 1 ) version (stealing method)
    bool deleteNode(LNode *p) {
          
          
        if (p == NULL || p->next == NULL)   // 这种方法存在缺陷
            // 当删除的结点位最后一个结点时,则只能从表头结点开始寻找p的前驱
            return false;
        LNode *q = p->next;
        p->data = q->data;
        p->next = q->next;
        free(q);
        return true;
    }
    

d. Find

  1. Bitwise search of the leading node:Average time complexity O ( n ) O(n)O ( n )
    LNode * getElem(linkList L, int i) {
          
          
        if (i < 1)
            return NULL;
        LNode *p = L;
        int j = 0;
        while (p!=NULL && j<i) {
          
          
            p = p->next;
            j++;
        }
        return p;
    }
    
  2. Lookup by value with head node:Average time complexity O ( n ) O(n)O ( n )
    LNode * locateElem(linkList L, int e) {
          
          
        LNode *p = L->next;
        while (p != NULL && p->data != e)
            p = p->next;
        return p;
    }
    
  3. Find the table length of the leading node:Average time complexity O ( n ) O(n)O ( n )
    int listLen(linkList L) {
          
          
        int len = 0;
        LNode *p = L;
        while (p->next != NULL) {
          
          
            p = p->next;
            len++;
        }
        return len;
    }
    

e. to establish

  1. The tail insertion method with the leading node establishes a singly linked list:
    // 带头结点的尾插法建立单链表
    linkList tailBuildLink_h(linkList &L) {
          
          
        int x;
        L = (linkList)malloc(sizeof(LNode));
        LNode *s, *r = L;
        scanf("%d", &x);
        while (x != 999) {
          
          
            s = (LNode *)malloc(sizeof(LNode));
            s->data = x;
            r->next = s;
            r = s;
            scanf("%d", &x);
        }
        r->next = NULL;
        return L;
    }
    
  2. The tail insertion method with tail nodes creates a singly linked list:
    linkList headBuildLink_h(linkList &L) {
          
          
        int x;
        L = (linkList)malloc(sizeof(LNode));
        L->next = NULL;
        LNode *s;
        scanf("%d", &x);
        while (x != 999) {
          
          
            s = (LNode *)malloc(sizeof(LNode));
            s->data = x;
            s->next = L->next;
            L->next = s;
            scanf("%d", &x);
        }
        return L;
    }
    

IV. Double Linked List

  1. Define the structure:
    typedef struct dNode {
          
          
        int data;
        struct dNode *prior, *next;
    }dNode, *dLinkList;
    
  2. Initialize the doubly linked list:
    bool initDLink(dLinkList &L) {
          
          
        L = (dLinkList)malloc(sizeof(dNode));
        if (L == NULL)
            return false;
        L->prior = NULL;
        L->next = NULL;
        return true;
    }
    
  3. Empty:
    bool emptyDLink(dLinkList &L) {
          
          
        return L->next == NULL;
    }
    
  4. Insert a node after the specified node:
    bool insertNextNode(dNode *p, dNode *s) {
          
          
        if (p == NULL || s == NULL)
            return false;
        s->prior = p;
        s->next = p->next;
        if (p->next != NULL)
            p->next->prior = s;
        p->next = s;
        return true;
    }
    
  5. Delete the node after the specified node:
    bool deleteNextNode(dNode *p) {
          
          
        if (p == NULL || p->next == NULL)
            return false;
        dNode *q = p->next;
        if (q->next != NULL)
            q->next->prior = p;
        p->next = q->next;
        free(q);
        return true;
    }
    
  6. Destroy the linked list:
    void destroyList(dLinkList &L) {
          
          
        while (L->next != NULL)
            deleteNextNode(L);
        free(L);
        L = NULL;
    }
    

V. Circular linked list

a. Circular singly linked list

Circular singly linked list:next next of the tail nodeThe n e x t pointer points to the head node
Compared with the singly linked list: starting from one node, any other node can be found
insert image description here

  1. Circular singly linked list structure definition:
    typedef struct clNode {
          
          
        int data;
        struct clNode *next;
    }clNode, *clList;
    
  2. Circular singly linked list initialization:
    bool initCList(clList &L) {
          
          
        L = (clNode *)malloc(sizeof(clNode));
        if (L == NULL)
            return false;
        L->next = L;
        return true;
    }
    
  3. Circular singly linked list judgment null operation:
    bool emptyCList(clList L) {
          
          
        return L->next == L;
    }
    
  4. Determine whether the node p is the end node:
    bool isTail(clList L, clNode *p) {
          
          
        return p->next == L;
    }
    

b. Circular double linked list

Circular double linked list:On the basis of the double linked list, the prior prior of the header nodep r i or points to the end node,the next nextn e x t points to the head node

  1. Structure definition:
    typedef struct cdNode {
          
          
        int data;
        struct cdNode *prior, *next;
    }cdNode, *cdLinkList;
    
  2. initialization:
    bool initCDLinkList(cdLinkList &L) {
          
          
        L = (cdNode *)malloc(sizeof(cdNode));
        if (L == NULL)
            return false;
        L->prior = L;
        L->next = L;
        return true;
    }
    
  3. Empty Judgment/ Tail Judgment:
    bool isEmpty(cdLinkList L) {
          
          
        return L->next == L;
    }
    bool isTail(cdLinkList L, cdNode *p) {
          
          
        return p->next == L;
    }
    
  4. Insert the s node after the p node:
    bool insertNextNode(cdNode *p, cdNode *s) {
          
          
        if (p == NULL || s == NULL)
            return false;
        s->next = p->next;
        s->prior = p;
        p->next->prior = s;
        p->next = s;
        return true;
    }
    
  5. Delete the successor node of p node:
    bool deleteNextNode(cdNode *p, cdNode *q) {
          
          
        if (p == NULL || q == NULL)
            return false;
        p->next = q->next;
        q->next->prior = p;
        free(q);
        return true;
    }
    

VI. Static linked list

Static linked list:Allocate a whole piece of contiguous memory space, and each node is centrally placed; each node contains two parts: data and a "pointer" pointing to the next node
insert image description here

  1. Define the structure:
#define maxSize 10
struct Node {
    
    
	int data;
	int next;
};
typedef struct Node sLinkList[maxSize];
  1. Briefly describe the basic operation implementation:
    1. Search : starting from the head node and traversing backwards
    2. The insertion order is iiThe node of i
      : create a new empty node and store the data;
      find thei − 1 i-1i1 node;the next next
      of the new nodeN e x t is modified toi − 1 i-1i1 n e x t next n e x t
      willi − 1 i-1i1 nodenext nextN ex t is modified to the position of the new node
    3. The deletion order is iiThe node of i
      : start from the head node to find thei − 1 i-1i1 node
      modifyi − 1 i-1i1 nodenext nextn e x t pointer
      will be theiinext next of i nodesn e x t pointer is set to -2

VII. Comparison of sequenced list and linked list

insert image description here

sequence table linked list
create Need to pre-allocate space, and it is not convenient to expand Only need to allocate a head node, and it is easy to expand
destroy (Static array) The system automatically reclaims space (Dynamic array) requires manual free Each node is free in turn
additions and deletions Need to move lots of elements O ( n ) O(n)O ( n ) Just modify the pointer, but the lookup also takes O ( n ) O(n)O ( n )
look up (bitwise search) O ( 1 ) O(1)O ( 1 ) ; (lookup by value)O ( log ⁡ 2 n ) O(\log2n)O(log2n ) _ Both require O ( n ) O(n)O ( n )

Guess you like

Origin blog.csdn.net/JackyAce6880/article/details/126064286