刪除包含特定數據的結點


任務描述

刪除鏈表的結點時,有時候不知道結點在哪,只知道結點數據的特征,如刪除成績低於60的學生結點、刪除學號為20160903的學生等。本關要求按照數據輸入的順序構建一個線性表,然后輸入待刪除節點數據信息,在鏈表中查找符合該信息的節點,並刪除;若不存在符合該數據信息的節點,則不操作。

編程要求

本關的編程任務是補全step5/deletehas.h文件中deletehas函數,以實現刪除線性表指定位置結點的要求。 // 函數deleteHas:刪除鏈表中data域為x的第一個節點,若不存在該節點,則操作 // 參數:h-鏈表頭指針,x-結點包含的數據 // 返回值:刪除結束后鏈表首結點地址 node * deleteHas(node * h, int x);

相關知識

程序可以分為兩步: 1、利用循環順序查找值為x的節點的**前驅節點**,並用指針P指向該前驅節點,若不存在值為x的節點,則前驅節點指針P為空; 2、前驅節點指針P不為空,則刪除值P指針指向的節點的后繼節點,刪除時注意釋放節點空間。

評測說明

本關中包含三個文件分別是: step5/deleteHas.h :此文件為學員文件,包含尾插法構建鏈表的函數實現。 step5/linkList.h:此文件包含鏈表常見操作的說明與實現,引用了deleteHas.h step5/test.cpp:此文件為評測文件(含main函數),引用“linkList.h”。 (上述三個文件可通過點擊在代碼取的右上角文件夾中的step5文件夾中查看) (注意:本關所實現鏈式線性表為帶頭結點的單鏈表) 以下是平台對step5/test.cpp的樣例測試集:

輸入輸出說明

輸入n(1<=n<=100),然后輸入n個整數,最后輸入待刪除元素x,按元素輸入書順序刪除首個x元素(若不存在則不刪除),輸出剩余元素,如下所示:(注意:鏈表的輸出函數已經實現,詳情請閱讀step5文件夾中的文件。)

測試輸入: 5 2 3 8 5 1 2 預期輸出: List: 3 8 5 1

測試輸入: 6 9 8 7 6 5 4 6 預期輸出: List: 9 8 7 5 4

test.cpp

#include "linkList.h"

int main()
{
    int n, i, num;
    node* t;
    node* head = new node;// 帶頭結點單鏈表,頭結點指針head
    head->next = NULL; // 頭結點head->next==NULL,鏈表為空
    //輸入結點數
    cin >> n;
    for (i = 0; i < n; i++)
    {
        //為新節點動態分配空間
        t = new node;
        cin >> t->data; //輸入結點數據
        t->next = NULL;  //結點指針域值為空
        //按輸入順序構建鏈表
        head = insertTail(head, t);
    }
    //輸入要刪除結點包含的數據
    cin >> num;
    //刪除包含num的結點
    head = deleteHas(head, num);
    //輸出鏈表
    printList(head);
    //刪除結點,釋放空間
    delList(head);

    return 0;
}

 

linkList.h

#include <iostream>
using namespace std;

// 定義結點結構
struct node
{
    int data;  // 數據域
    node* next;  // 指針域,指向下一個結點
};

// 函數deleteHas:刪除鏈表中data為x的結點,如果有多個這樣的結點,只刪除第一個,若不存在data為x的節點,則不操作
// 參數:h-鏈表頭指針,n-結點包含的數據
// 返回值:刪除結束后鏈表首結點地址
node* deleteHas(node* h, int x);


// 函數insertTail:鏈表尾部插入
// 參數:h-鏈表頭指針,t-指向要插入的結點
// 返回值:插入結點后鏈表的頭結點地址
node* insertTail(node* h, node* t);

// 函數printList:輸出鏈表,每個數據之間用一個空格隔開
// 參數:h-鏈表頭指針
void printList(node* h);


// 函數delList:刪除鏈表,釋放空間
// 參數:h-鏈表頭指針
void delList(node* h);


#include "deleteHas.h"

//函數delList:刪除鏈表,釋放空間
//參數:h-鏈表頭指針
void delList(node* h)
{
    node* p = h; //指針p指向頭結點,第一個要刪除的結點
    while (p) //這個結點是存在的
    {
        h = h->next; //頭指針h指向下一個結點(下一個結點的地址存在當前結點的指針域中,即h->next中
        delete p; //刪除p指向的結點
        p = h; //p指向當前的頭結點,即下一個要刪除的結點
    }
}
//函數printList:輸出鏈表,每個數據之間用一個空格隔開
//參數:h-鏈表頭指針
void printList(node* h)
{
    cout << "List:";
    h = h->next;
    while (h)
    {// h為真,即h指向的結點存在,則輸出該結點的數據
        cout << " " << h->data;  // 輸出結點數據
        h = h->next;  // 將該結點的指針域賦值給h,h就指向了下一個結點
    }
    cout << endl; // 輸出換行符
}


node* insertTail(node* h, node* t)
{
    // 請在此添加代碼,補全函數insertTail
    /********** Begin *********/

    node* p = h;
    // 讓p指向最后一個結點
    while (p->next)
        p = p->next;
    p->next = t; // 讓最后一個結點的指針域指向結點t
    t->next = NULL; // 鏈表尾指針置為NULL
    return h;  // 返回第一個結點的地址(即鏈表頭指針)
    /********** End **********/
}

 

deleteHas.h

// 函數deleteHas:刪除鏈表中data為x的結點,如果有多個這樣的結點,只刪除第一個
// 參數:h-鏈表頭指針,n-結點包含的數據
// 返回值:刪除結束后鏈表首結點地址
node* deleteHas(node* h, int n)
{
  // 請在此添加代碼,補全函數deleteHas 
   /********** Begin *********/
    node *p = NULL, *q = h;  // p為要刪除結點的前結點,q指向要刪除結點
    while(q)
    {// h為真,即h指向的結點存在
        if(q->data == n)
            break; // 找到了
        if(q->next == NULL)  // 后面沒有結點了,沒有結點滿足條件
            return h;  // 不刪除,直接返回
        // 繼續往后找,兩個指針一起后移
        p = q;
        q = q->next;
    }
    // 刪除q指向的結點
    if(p == NULL)  // 刪除頭結點
    {
        h = q->next;  // 下一個結點變成頭結點
        delete q;  // 刪除結點
        return h;
    }
    // 不是頭結點
    p->next = q->next;  // 把q指向結點的指針域(q后面結點的地址)賦值給p指向結點的指針域
    return h;
    /********** End **********/
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM