链表是一种物理存储单元上非连续、非顺序的存储结构。//相较于顺序存储结构:数组。

链表可以是单(向)链表,也可以是双(向)链表。//双向链表可以说是单向链表上的改进,这样子方便对节点的前驱节点进行操作。

*(੭*ˊᵕˋ)੭*ଘ 也可以是循环链表,顾名思义,就是头尾相连的链表//目前是在做约瑟夫环的链表实现的时候用过。

本小文内容就单链表的 建立,遍历,查找,插入,删除 内容进行整理

struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) :
            val(x), next(NULL) {
    }
};

单链表的建立,一般有两种:头插法和尾插法。

ListNode* CreatelinklistA1() {//头插法,无头哨兵节点
    ListNode* head = NULL, * p = NULL;
    int x;
    for (int i = 0; i < 5; i++) {        
        cin >> x;
        p = new ListNode(x);
        p->next = head;
        head = p;
    }
    return head;
}
ListNode* CreatelinklistA2() {//头插法,有哨兵节点
    ListNode* head = NULL, * p = NULL;
    head = new ListNode(-1);//哨兵节点
    int x;
    for (int i = 0; i < 5; i++) {        
        cin >> x;
        p = new ListNode(x);
        if (head->next == NULL)  head->next = p;
        else {
            p->next = head->next;
            head->next = p;
        }
    }
}

 

ListNode* CreatelinklistB1() {//尾插法,无头哨兵节点
    ListNode* head = NULL, * p = NULL,*end=NULL;
    int x;
    for (int i = 0; i < 5; i++) {        
        cin >> x;
        p = new ListNode(x);
        if (end == NULL) {
            end = p;
            head = end;
        }
        else {
            end->next = p;
            end = p;       
        }
    }
    return head;
}
ListNode* CreatelinklistB2() {//尾插法,头哨兵节点
    ListNode* head = NULL, * p = NULL,*end=NULL;
    head = new ListNode(-1);
    int x;
    for (int i = 0; i < 5; i++) {        
        cin >> x;
        p = new ListNode(x);
        if (end == NULL) {
            end = p;
            head->next = end;
        }
        else {
            end->next = p;
            end = p;       
        }
    }return head;
}

 

链表的遍历

void DisplayList(ListNode *head) {
    while (head != NULL) {//这里是无哨兵节点的遍历,如果有的话,谨记第一个元素是从head->next开始的
        cout << head->val << endl;
        head = head->next;
    }
}

 

查找

ListNode* FindElement(ListNode* head, int num) {
//    ListNode* p;
    while (head != NULL) {
        if (head->val == num) return head;
        head = head->next;
    }
    return NULL;
}

插入:

插入的操作=先查找,找到插入节点的位置,再把插入的节点的指针(以及前面节点的指针进行修改)

ListNode* InsertElement(ListNode* head, int num, int k)//在第k个元素后面插入
{
    if (k < 0) return NULL;
    ListNode* p,*pre,*q;
    q = new ListNode(num);
    pre = p = head;
    for (int i = 0; i < k; i++) {
        pre = p;
        p = p->next;
    }
    pre->next = q;
    q->next = p;
    return head;
}

 

删除:

先查找,后删除,同样对指针进行处理  

代码关键在于:pre->next=p->next; free(p);

如果是删除整个链表的话,可以摘一个,释放一个。p=head; head=head->next; free(p).

posted on 2020-01-22 19:33  夜隳·依子  阅读(164)  评论(0编辑  收藏  举报