The first blog jobs - Linear table

0.PTA score Screenshot

1. This week learning summary

Table 1.1 summarizes the linear content

* A sequence table:

  • Sequence table storage structure: all the elements in the linear form for storing in the order of sequence table storage structure becomes.

  • The advantages and disadvantages of storage order:

优点:
1.逻辑相邻,物理相邻
2.无须为表示表中元素之间的顺序关系增加额外的存储空间
3.可随机存取任一元素
4.存储空间使用紧凑
缺点:
1.插入、删除操作需要移动大量的元素(除操作在表尾的位置进行外)
2.预先分配空间需按最大空间分配,利用不充分 
3.表容量难以扩充
  • Features of the sequence table: 1 i.e., adjacent implemented physical address logically adjacent data elements;
    2 may be implemented in random access data elements; (stored in the form of an array)
    illustrated as follows:

  • Structure is defined sequence table:
    Stack Area example:

typedef int ElemType; 
typedef struct 
{   
    ElemType data[MaxSize];     //存放顺序表元素
    int length ;                //存放顺序表的长度
} List; 
typedef List *SqList;

Heap examples:

Basic operation order table *

  • :( initialization sequence table to create a new list)
void CreateList(SqList& L, int n)
{
    int index = 0;
//初始化顺序表
    L = new List;
    L->length = n;
    //给表中数据元素赋值
    while (n--)
        cin >> L->data[index++];
}

  • Deletion order table :( time complexity of O (1))
void DeleteList(SqList* &L)
{
    delete L;
}
  • Determine whether the empty table:
bool ListEmpty(List L)
{
    return(L->length == 0);
}
  • Length calculation table:
int ListLength(List L)
{
    return(L->length);
}
  • The output data sequence table :( time complexity of O (n))
void DispList(List L)
{
    int i;
    if (L->length == 0)
    {
        cout << "NULL";
    }
    else
    {
        for (i = 0; i < L->length; i++)
            cout << L->data[i] << " ";
    }
}
  • Sequence table lookup data:
    Find :( i-th element of the time complexity of O (1))
返回L中第i个元素的值,存放在e中。1≤i≤ListLength(L)
bool GetElem(List L,int i,ElemType &e){ 
    if (i<1 || i>L->length)
        return false;
    e=L->data[i-1]; 
    return true;
}

Find :( element value by the time complexity of O (n))

将顺序表中的元素逐个和给定值 e 相比较。
int LocateElem(List L, ElemType e){
    for(int i=0; i<L->length;i++)
        if(L->data[i]==e)
            return i+1;       //返回元素的逻辑位序
    return 0;
}
  • Inserting data sequence table (the time complexity of O (n))

Insert Code Data:

bool ListInsert(List &L,int i,ElemType e)
{  int j;
   if (i<1 || i>L->length+1)
    return false;   //参数错误时返回false
   i--; //将顺序表逻辑序号转化为物理序号
for (j=L->length;j>i;j--)   //将data[i..n]元素后移一个位置
  L->data[j]=L->data[j-1];
L->data[i]=e;           //插入元素e
L->length++;            //顺序表长度增1
return true;            //成功插入返回true
}

Note insert data points:

The number of mobile elements:

  • When i = n + 1, the number of the mobile is 0;
  • i, the mobile number n-i + 1
  • When i = 1, the mobile number is n, reaches its maximum.
  • A total of n + 1 is inserted into position, the probability pi = 1 / n + 1
  • The average number of mobile elements as:

  • Table of elements in order to delete

    the relevant code:

bool ListDelete(List &L,int i,ElemType &e)
{  
   if (i<1 || i>L->length) //删除位置不合法
        return false;
   i--;         //将顺序表逻辑序号转化为物理序号
   e=L->data[i];
   for (int j=i;j<L->length-1;j++)         
      L->data[j]=L->data[j+1];
   L->length--;     //顺序表长度减1
   return true;         
}

Removing elements time complexity:

  • When i = n, the number of the mobile is 0;
  • When i = 1, times of movement n-1.
  • Suppose pi is the probability of deleting the i-th position on the element: 1 / n
  • The average number of times the desired length of the n-movement linear elements to delete a table elements:

* Two single list:

Chain is a linear chain table storage

  • Structure:
    Node = + Pointer Data element
    1. Element: storing data
    2. pointers: a storage element of the storage location in the node
    shown in the list is:

  • List structure definition:

  • Node pointer lead:

    to a linear memory address in the first table as an address data element a1 linear form, called linear head pointer list.
    For ease of operation times, before the first virtual node plus a "head node", to point to the head node pointer of the head pointer list.

Benefits provided first node:
⒈ first element facilitates the processing nodes:
the first element stored node address pointer field in the header node, the operation in the first position in the list and other locations on the same, without the need for special treatment;
⒉ facilitate unitary empty tables and non-empty list:
whether the list is empty, the head pointer is pointing to a non-null pointer to the head node, the processing of non-null empty list table also unified.
That is:

a singly linked list is uniquely determined by the header, so a single linked list can be used to name the name of the head pointer, the head pointer if the name is L, put the list referred to in Table L.

  • Initialization list:
typedef struct LNode{
     ElemType   data;       //数据域
     struct LNode  *next;   //指针域
}LNode,*LinkList; 
Status InitList_L(LinkList &L){ 
   L=new LNode;  此处若写为L=new LinkList 错误,L要申请LNode大小的内存空间                    
   L->next=NULL;     
   return OK; 
} 
  • Create a new list:
    1. Head interpolation established chain (linked list the new node is inserted from the head):

    codes for the new node is inserted as s:
    S-> Next = L-> Next;
    L-> Next = s;

* Head plug the established chain of Law Code:

void CreateListF(LinkList &L,ElemType a[],int n){
    int i;
           L=new LNode;
    L->next=NULL;   
          LinkList nodePtr;
    for(i=0;i<n;i++){
         nodePtr=new LNode;//每个节点都要动态申请空间
         nodePtr->data=a[i];
         nodePtr->next=L->next;
        L->next= nodePtr;
    }
}

2. interpolation tail established chain (linked list the new node is inserted from the tail):

the new node into the linked list table on the tail current must be added a tail pointer r, always point to the end node of the current list.
eg: tail pointer: R & lt
R-> Next = S;
R & lt = S
benefit of adding tail pointer: outputting output a whole chain content rather than a node, can protect the head node, adding a new node not every traverse the list Looking for a last node.

* Code tail interpolation:

void CreateListR(LinkList &L,ElemType a[],int n){
    int i;
    LinkList  nodePtr,tailPtr;
            L=new LNode;
    L->next=NULL;   
    tailPtr=L;//尾指针
    for(i=0;i<n;i++)  {
        nodePtr=new LNode;
        nodePtr->data=a[i];
        rearPtr->next=s;//尾部插入新结点
        rearPtr=s;  }
       nodePtr->next=NULL;
}
  • Destruction list:
    the list of the order table for different destruction, not to delete the entire chain according to the header node address, because the address of each node in the chain are not necessarily contiguous, so that each node to be deleted one by one.
void DestroyList(LinkList &L){
    LinkList p;
    while(L){
        p=L;
        L=L->next;
        delete p;   
    }
}
  • Judgment empty table:
bool ListEmpty(LinkList *L)
{
  return(L->next==NULL);
}
  • Length calculation table:
int ListLength(LinkList L)
{ int n=0;
  LinkList p=L->next;   
   while (p)
   {    n++;
    p=p->next;
   }
   return(n);   //p指向尾节点,n为节点个数
}
  • Output lists:
void DispList(LinkList L)
{
    int flag = 1;
    LinkList p = L->next;
    while (p)
    {
        if (flag)
        {
            cout << p->data;
            flag = 0;
        }
        else
        {
            cout << " " << p->data;
        }
        p = p->next;
    }
}
  • Find data elements:
    the data elements of the list is not as linear as the table of random access needs to traverse the list
bool GetElem(LinkList L,int i,ElemType &e)
{  int j=0;
   LinkList p=L;    //p指向头节点,j置为0(即头节点的序号为0)
   while (j<i && p!=NULL)   //找第i个节点
   {    j++;
    p=p->next;
   }
   if (p==NULL) //不存在第i个数据节点,返回false
    return false;
   else     //存在第i个数据节点,返回true
   {  e=p->data;
    return true;
   }
}
  • Insert Element:

    Let p points to ai-1, s point e, then insert the code as:
    S = new new LNode;
    S-> Data = E;
    S-> Next = p-> Next;
    p-> Next = S;

* Data elements inserted prior to the L e i th element:

bool ListInsert(LinkList &L,int i,ElemType e){
  int j=0;
  LinkList p=L,s;
  while(p&&j<i-1){
    j++;p=p->next;
  }//查找第i-1个节点
  if(p==NULL) return false; //未找到第i-1个结点
  s=new LNode;
  s->data=e;
  s->next=p->next;  //插入p后面
  p->next=s;    
  return true;
}
 
  • Delete data elements:
    Remove the i-th node in a single linked list of basic operations: finds the first i-1 nodes linear table, which is directed to the subsequent modification of pointers.


Delete data elements node q:
q = p-> Next;
p-> = Q- Next> Next;
E = Q-> Data;
Delete q;

* Delete data elements Code:

bool ListDelete_L(LinkList &L,int i,ElemType &e)
{
     int j=0;
  LinkList p=L,s,q;
  while(p&&j<i-1){  
    p=p->next;j++;//指针每次next前都要判断是否空指针
  }
  if(p==NULL) return false;

    q=p->next;  //第i个位置
  if(q==NULL) return false; 
      e=q->data;
      p->next=q->next;//改变指针关系,删除
      delete q;
     return true;
}
  • List Summary:
    1. The process of traversing the list is important to consider whether the pointer is NULL, in particular p-> Next or p-> p is important to consider whether the empty former Data
    2. list changes, often reconstructed. Reconstruction of practice:
    the p-of L-=> the Next; of L-> the Next = NULL;
    3. lists as delete, pay attention to consider the case of the list was empty
    4. lists as insertion time, pay attention to know where the precursor pointer at the insertion point can be obtained by pre-> next.
    5. To retain the successor pointers, may be designed nextptr = p-> next, intermediate changes p, then p = nextptr.
    6. Chain design, drawing to understand the current state pointer.

* III. Ordered list

  • Different ordered list and order list, the order table is a logical physically adjacent, i.e. neighboring data element address. The sorted list is the value of the data element was in the form of ascending or descending order.
  • The logical relation between the linear form and the ordered list of elements, which difference is the operation implemented.

  • Ordered insert table data:

    The insertion method can be divided into two different search order:
    * 1: the first find shift:

void ListInsert(SqList &L,ElemType e)
{     int i=0,j;
      while (i<L->length && L->data[i]<e)
    i++;            //查找值为e的元素
      for (j=ListLength(L);j>i;j--) //将data[i..n]后移一个位置
    L->data[j]=L->data[j-1]; 
      L->data[i]=e;
      L->length++;      //有序顺序表长度增1
}

* Method 2: while looking for edge shift:

void InsertSq(SqList &L,int x)
{
    for(int j = L->length; j > 0; j--)
    {
        if (x >= L->data[j-1]) //找
        {
            L->data[j] = x;
            break;
        }
        L->data[j] = L->data[j-1];//移动,边移边找
        L->data[j-1] = x;//保证第一个数据插入
    }
    L->length++;

}

There are different methods according to the structure defined by 3:

void ListInsert(LinkNode &L,ElemType e)
{     LinkNode pre=L,p;

      while (pre->next!=NULL && pre->next->data<e)
    pre=pre->next;  //查找插入结点的前驱结点*pre

      p=new LinkNode;
      p->data=e;        //创建存放e的数据结点*p
      p->next=pre->next;    //在*pre结点之后插入*p结点
      pre->next=p;

}
  • Ordered list merge
    1. ordered list LA (m elements) and LB (n elements) into a sorted list LC:
    Thinking "" 2 while scanning the sorted list LA, LB, comparison LA, LB elements, the smaller the insertion element the combined list LC, repeat the process until an ordered table scan is completed. The remaining elements are inserted into the table ordered LC.
    The time complexity of this algorithm is O (m + n), the spatial complexity is O (m + n).
新建顺序表LC
i表示LA的下标,j表示LB的下标
while(i<LA.length&&j<LB.length)
{
      if (LA->data[i]<LB->data[j])   则LC中插入元素LA->data[i],i++   
      else 插入元素LB->data[j],j++   
      LC数组长度增1.
}     
查看LA或LB是否为扫描完毕,没扫描完的把剩余元素复制并插入LC

* Ordered list merge the relevant code:

void UnionList(SqList  LA,SqList  LB,SqList  &LC)
{     int i=0,j=0,k=0;//i、j分别为LA、LB的下标,k为LC中元素个数
      LC=new SqList;        //建立有序顺序表LC
      while (i<LA->length && j<LB->length)
      { if (LA->data[i]<LB->data[j])
    {     LC->data[k]=LA->data[i];
           i++;k++;
    }
    else    //LA->data[i]>LB->data[j]
    {     LC->data[k]=LB->data[j];
          j++;k++;
    }
       }   
     while (i<LA->length)       //LA尚未扫描完,将其余元素插入LC中
     {  LC->data[k]=LA->data[i];
    i++;k++;
     }
     while (j<LB->length)       //LB尚未扫描完,将其余元素插入LC中
     {  LC->data[k]=LB->data[j];
    j++;k++;
     }
     LC->length=k;
}

!!一定要注意有序表是否遍历完全的情况

2. The ordered list L1 and L2 are incorporated into the ordered list L1:

* list still use the original storage space two linked lists, not otherwise occupied by other storage space.
Ideas: reconstruction L1 list, p pointer L1 save the original list.
Meanwhile traversal L1, L2 list, the smaller element in the linked list L1. Until a list scanned. There continues to be inserted list elements remaining in L1.
The relevant code is:

void MergeList(LinkList& L1, LinkList L2)
{
    LinkList p,q,tail,temp;
    p = L1->next;
    q = L2->next;
    L1 = new LNode;
    L1->next = NULL;
    tail=L1;
    while (p && q)
    {
        if (p->data < q->data)
        {
            temp = p;
            p = p->next;
        }
        else if (p->data > q->data)
        {
            temp = q;
            q = q->next;
        }
        else
        {
            temp = p;
            p = p->next;
            q = q->next;
        }
        tail->next=temp;
        tail=temp;
    }
    while (p)
    {
        tail->next = p;
        tail=p;
        p = p->next;
    }
    while (q)
    {
        tail->next = q;
        tail=q;
        q=q->next;
    }
    tail->next=NULL;
}
  • Ordered list data is deleted:
先遍历链表找到要删除的元素e,查看它为第几个元素,假设e为第i个元素
then 找到第i-1个节点
    将第i-1个节点的后继改为第i+1个节点
    删除第i个节点

And delete the list of similar structure

* Four pairs of lists:

Each node has a doubly linked list 2 pointer field, a pointer to a subsequent node, a node points to the predecessor.

Type is defined as follows:

typedef struct DNode       //声明双链表节点类型
 {  ElemType data;
   struct DNode *prior;    //指向前驱节点
    struct DNode *next;     //指向后继节点
  } DLinkList;

  • Lead doubly linked list node:

  • Doubly linked list of advantages:
    1. The starting can quickly find its precursor and successor node node from any node;
    2 from any one node can access other nodes.

  • Doubly linked list insert node:
    for example, in after the insertion node junction p s

    related action statement:

 s->next = p->next
 p->next->prior = s
 s->prior = p
 p->next = s
  • : Doubly linked list node delete
    a node after the node such as deleting * p

Related operations statement:

 p->next->next->prior = p
 p->next = p->next->next

  • The first interpolation method to establish the doubly linked list:
    Create the First Node array contains n elements a double linked list L.

Head interpolation method to build the list of code:

void CreateListF(DLinkNode *&L,ElemType a[],int n)
{  DLinkNode *s; int i;
       L=(DLinkNode *)malloc(sizeof(DLinkNode));    //创建头结点
       L->prior=L->next=NULL;   //前后指针域置为NULL
       for (i=0;i<n;i++)        //循环建立数据结点
       {    s=(DLinkNode *)malloc(sizeof(DLinkNode));
    s->data=a[i];       //创建数据结点*s
    s->next=L->next;    //将*s插入到头结点之后
    if (L->next!=NULL)          //若L存在数据结点,修改前驱指针
           L->next->prior=s;
    L->next=s;
    s->prior=L;
       }
} 
  • Establishing tail interpolation doubly linked list:
    Create the lead node from the array a doubly-linked list of n elements containing L.

    Code tail established chain interpolation:
void CreateListR(DLinkNode *&L,ElemType a[],int n)
{     DLinkNode *s,*r;
       int i;
       L=(DLinkNode *)malloc(sizeof(DLinkNode));    //创建头结点
       L->prior=L->next=NULL;   //前后指针域置为NULL
       r=L;         //r始终指向尾结点,开始时指向头结点
       for (i=0;i<n;i++)        //循环建立数据结点
       {      s=(DLinkNode *)malloc(sizeof(DLinkNode));
    s->data=a[i];       //创建数据结点*s
    r->next=s;     
              s->prior=r;   //将*s插入*r之后
    r=s;            //r指向尾结点
      }
      r->next=NULL;     //尾结点next域置为NULL
}

* V. circular list

Circular list is another form of storage structure in the form of a chain.

Circulation singly linked list:


  • Differs from the single list:
    1, from a position in any node of the circular list can be found in all the other nodes, and can not singly linked lists;
    2. no obvious circular list tail cycling conditions:
Single list Circular list
First Node p->next!=NULL p->next!=L
Without head node p!=NULL p!=L
  • Circular doubly-linked circular and single chain:

Acyclic and cyclic doubly linked list doubly linked list of differences:

1.2 linear meter of understanding and learning experience:

Linear table is a linear structure of the logical structure of data, according to its structure may be different storage arrays and separated list of class two kinds, some basic arithmetic operations of data after dispensing. Linear list is a finite sequence of data elements having the same characteristics.

  • Linear table generally expressed as:

  • Linear characteristic table is:

    Learning experience: the feeling of setting the relationship between this list each node, depending on the complexity of the algorithm will be very different, sometimes circles around in the end do not understand when to point to the next node; feeling a lot of the code is to be set according to the structure of the algorithm stack area and heap area, the basic initialization and other routine operations will remember a simple point.

2.PTA lab assignments

Table 2.1 -6-1 jmu-ds- linear section delete data

实现在顺序表中删除某个区间数据。需要实现下述的三个函数完成该功能。
void CreateList(SqList &L,int n);//建顺序表,L表示顺序表指针,n表示输入数据个数。 
void DelNode(SqList &L,int min,int max);//删除区间元素。min,max表示删除的区间 
void DispList(SqList L); //输出顺序表内容 ,数据间空格隔开,尾部不能有空格。

2.1.1 Code Screenshot




2.1.2 The title PTA submit a list of instructions

Q1:运行超时:在建链表输入数据时将循环条件写成了n>0;导致无限循环
A1:将n>0修改为正确的n--
Q2:部分正确:在控制区间时,查找在区间的元素没有考虑相等的情况
A2:将查找条件改为L->data[index] >= min && L->data[index] <= max

2.2 ds-test-7-1 the intersection of two ordered list of sequences

已知两个非降序链表序列S1与S2,设计函数构造出S1与S2的交集新链表S3。
输入分两行,分别在每行给出由若干个正整数构成的非降序序列,用−1表示序列的结尾(−1不属于这个序列)。数字用空格间隔。
在一行中输出两个输入序列的交集序列,数字间用空格分开,结尾不能有多余空格;若新链表为空,输出NULL。

2.2.1 Code Screenshot




2.2.2 The title PTA submit a list of instructions


! ! : The submission is content after another and then modify the wrong title set, when submitting there have been a lot of problems.

Q1:编译错误:在将两个列表的交集存入新链表S3时,有个别表头名称弄混造成编译错误
A1:把写错的L改成了正确的S3,因为惯性就写成L了
Q2:部分正确:输出时忘记考虑表S为空表的情况
A2:在DispLinkList()函数中添加上题干要求的if (!p)  cout << "NULL";的语句来表示S为空表的情况。

Table 2.3 linear -6-3 jmu-ds- delete duplicate sequence table element

设计一个算法,从顺序表中删除重复的元素,并使剩余元素间的相对次序保存不变。
输入格式: 第一行输入顺序表长度。 第二行输入顺序表数据元素。中间空格隔开。
输出格式:数据之间空格隔开,最后一项尾部不带空格。
输出删除重复元素后的顺序表。

2.3.1 Code Screenshot


2.3.2 The title PTA submit a list of instructions

Q1:部分正确:没考虑到表中元素全部重复的情况
A1:把循环条件next<L->length改为next<=L->length,如果全部重复,只留下第一个元素。
Q2:输出错误:输出空格时将flag初始成了0;造成编译错误
A2:把条件改为(flag=1)时不输出前置空格,再在循环中将后面的flag改为0,都输出前置空格;

3. Read Code

3.1 Title and problem-solving Code

  • topic:

  • Problem-solving Code:

class Solution {
  public ListNode rotateRight(ListNode head, int k) {
    // base cases
    if (head == null) return null;
    if (head.next == null) return head;

    // close the linked list into the ring
    ListNode old_tail = head;
    int n;
    for(n = 1; old_tail.next != null; n++)
      old_tail = old_tail.next;
    old_tail.next = head;

    // find new tail : (n - k % n - 1)th node
    // and new head : (n - k % n)th node
    ListNode new_tail = head;
    for (int i = 0; i < n - k % n - 1; i++)
      new_tail = new_tail.next;
    ListNode new_head = new_tail.next;

    // break the ring
    new_tail.next = null;

    return new_head;
  }
}

3.1.1 The problem of design ideas

  • Time complexity: O (n)
  • Space complexity: O (1)

3.1.2 the question pseudocode

Retrograde linked list algorithm similar:
the data elements are connected together, so that can define the number of movements;
find the corresponding position of the loop is disconnected, determines the head of the list and the new end of the list
to find old tail portion connected to the head of the list and old_tail.next = head, the entire list as a closed loop, while the calculated chain length n.
Find a new tail, the (n - k% n - 1 ) nodes, the new head of the list is the first (n - k% n) nodes.
Disconnect ring new_tail.next = None, and returns the new list head new_head.


public ListNode rotateRight(ListNode head, int k) {
    if (为空表) return NULL
    if (旋转结束) return 表头

    定义头结点
    int n;
    for (n = 1; 没走到目的节点; n++)
        当前指针后移一位
        当前指针的后继成为首节点
    end for
    ListNode new_tail = head;
    for (int i = 0; i < n - k % n - 1; i++)//旋转次数超过表中元素个数开始循环
        new_tail = new_tail.next;
    ListNode new_head = new_tail.next;

    end for
    结束循环

    return new_head;
}

3.1.3 operating results

3.1.4 Analysis of the advantages and difficulties of solving the topic.

优势:
此做法巧妙在把链表连成了一个环,在移动节点时不用过多的去关注链表是否遍历到尾部的问题
难点:
难点在于当前指针和新首节点以及最后一个指针之间的关系转换,即old_tail和new_tail

3.2 Title and problem-solving Code

  • topic:

  • Code:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
        struct ListNode* partition(struct ListNode* head, int x){
    struct ListNode headLess, headGreater;
    struct ListNode *curLess, *curGreater;
    
    headLess.next = headGreater.next = NULL;
    curLess = &headLess; curGreater = &headGreater;
    
    while(head){
        if(head->val < x){
            curLess->next = head;
            curLess = curLess->next;
        }else{
            curGreater->next = head;
            curGreater = curGreater->next;
        }
        head = head->next;
    }
    curGreater->next = NULL;
    curLess->next = headGreater.next;
    
    return headLess.next;
}
}

3.2.1 The problem of design ideas


Time complexity: O (N)
space complexity: O (N)

3.2.2 the question pseudocode

/**
 * 维护两个链表,一个所有值小于x,一个所有值大于等于x,
 * 遍历原始链表,当值小于x时。curLess指向该节点,
 * 当值大于等于x时,curGreater指向该节点。
 */
struct ListNode* partition(struct ListNode* head, int x)
{
    定义两个链表,一个所有值小于x,一个所有值大于等于x:headLess, headGreater;
    struct ListNode* curLess, * curGreater;

    链表初始化
    curLess = &headLess; curGreater = &headGreater;

    while (不为空表) {
        if (表中元素小于x )  在表curLess中插入此数据
        end if
        else (表中元素大于x) 在表curGreater中插入此节点
        end else
        原表当前指针后移进行遍历
    }
    end while
    将表curGreater拼接到表curLess后

    return headLess.next;
}

3.2.3 operating results

3.2.4 Analysis of the advantages and difficulties in problem solving topics

优势:
设置两个链表来分别存储比x大和比x小的节点;
很好的保护了各个数据元素的原始位置;
用引用来保护要返回地址的头结点
难点:
链表拆分,临时节点,不能成环

Guess you like

Origin www.cnblogs.com/zyc01-jm/p/12435738.html