刪除單鏈表中的重複節點
一、題目描述
已知單鏈表L,寫一算法,刪除其中的重複節點。(更好的閱讀體驗,請訪問程序員在旅途)
二、分析解答
2.1 知識點分析
本題主要考察鏈表的相關知識點,其中包括:單鏈表的結構、創建、遍歷、刪除等操作。要想熟練的使用鏈表,必須對這些有着清楚的認識。
鏈表是線性結構的一種物理實現,除此之外,線性結構還可以使用順序存儲結構來實現。順序存儲是使用內存中的一塊地址連續空間順序存放線性表中的每一個元素,每個元素在物理上相鄰,而鏈式存儲結構則不會要求物理上的元素相鄰,它通過節點的指針域指向下一個元素。
線性結構是數據結構的幾種常見邏輯結構之一,在數據結構中,常見的邏輯結構有:集合結構、線性結構、樹結構、圖結構。這幾種邏輯結構,如果要在計算機上實現出來,可以採用順序存儲結構、鏈式存儲結構、索引結構、散列結構四種。從理論上講,任何一種邏輯結構都可以採用任何一種物理結構來實現。
在單鏈表的創建過程中,根據新元素插入位置的不同,可以有頭插法和尾插法兩種。這兩種創建方式創建出來的單鏈表在性質上沒有什麼不同。
爲了方便單鏈表元素的統一操作,也可以在單鏈表的頭部附加一個結點,我們稱之爲 頭結點。頭結點中的數據域可以存放和鏈表有關的信息,例如節點的個數。要注意頭結點和頭指針在邏輯上的區別,鏈表中第一個正式數據元素的節點叫做首元結點,在此節點之前附加的一個節點叫做頭結點,頭結點中數據域存儲的信息在性質上和鏈表中數據元素節點中數據域存儲的內容不同,頭指針是指向整個鏈表中的第一個節點的地址,可能是頭結點的地址,也可能會是首元結點的地址。
2.2 代碼分析
#include<stdio.h>
#include<stdlib.h>
typedef struct node{
int data;
struct node *next;
}Node,*PNode;
//頭插法建立帶有頭結點的單鏈表
PNode creat_list(){
//申請頭結點
PNode head = (PNode)malloc(sizeof(Node));
head->next = NULL;
scanf("%d",&(head->data)); // 頭結點的數據域可以存放總結點數
//新增元素
PNode p = NULL;
int i;
for(i=0;i<(head->data);i++){
p = (PNode)malloc(sizeof(Node));
scanf("%d",&(p->data));
//這是頭插法的關鍵所在
p->next = head->next;
head->next = p;
}
return head;
}
//刪除重複節點
void del_repeated_node(PNode head){
PNode k = head->next, pre_p = k, p = pre_p->next;
//遍歷單鏈表的每一個節點
while(k && k->next != NULL){
//判斷k後面的節點是否與k的值域重複,如果重複,則刪去。
while(p){
if(k->data == p->data){
//刪除重複的p節點
PNode temp = p;
pre_p ->next= p->next;
p = pre_p->next;
free(temp);
}else{
pre_p = pre_p->next;
p = pre_p->next;
}
}
k = pre_p = k->next;
p = pre_p->next;
}
}
void print_list(PNode head){
PNode p = head->next;
while(p){
printf("p->data: %d \t",p->data);
p = p->next;
}
printf("\n");
}
int main(){
PNode head = creat_list();
print_list(head);
del_repeated_node(head);
print_list(head);
return 0;
}
2.3 結果截圖