1. 程式人生 > >資料結構-連結串列-練習題1

資料結構-連結串列-練習題1

題目

2.已知一個帶表頭結點的單鏈表,結點結構為data、link,假設該連結串列只給出了頭指標list。
在不改變連結串列的前提下,請設計一個儘可能高效的演算法,查詢連結串列中倒數第k個位置上的結點(k正為整數)。
若查詢成功,演算法輸出該結點的data域的值,並返回1;否則,只返回0.要求:
(1)描述演算法的基本設計思想;
(2)描述演算法的詳細實現步驟;
(3)根據設計思想和實現步驟,採用程式設計語言描述演算法,關鍵之處請給出簡要註釋。

程式碼實現

時間複雜度Q(n)

#include <stdio.h>
#include
<stdlib.h> #include <stdbool.h> //建立一個整型的連結串列 typedef struct _NumNode NumNode; struct _NumNode{ int num; NumNode * next; }; //定義一個指標的佇列 //資料區域 typedef struct _Node Node; struct _Node{ NumNode * numNode; Node * next; }; //控制區域 typedef struct _Queue Queue; struct _Queue{ Node *
Front; Node * Rear; }; //佇列實現 //建立一個佇列 Queue * creatQueue(){ Node * node=(Node *)malloc(sizeof(Node)); node->next=NULL; Queue * queue=(Queue *)malloc(sizeof(Queue)); queue->Front=node; queue->Rear=node; return queue; } //判斷是否為空 bool isEmpty(Queue * queue){ return
(queue->Front==queue->Rear); } //入隊 void addQueue(Queue * queue,NumNode * numNode){ //建立一個節點 Node * node=(Node *)malloc(sizeof(Node)); node->numNode=numNode; node->next=NULL; //將節點放入佇列 queue->Rear->next=node; //將Rear指向心得節點 queue->Rear=node; } //出隊 NumNode * DeleteQ(Queue * queue){ if(isEmpty(queue)){ return NULL; } else{ Node * node=queue->Front->next; NumNode * numNode=node->numNode; queue->Front->next=node->next; free(node); return numNode; } } //整形連結串列實現 //建立 NumNode * creatNumNode(){ NumNode * numNode=(NumNode *)malloc(sizeof(NumNode)); numNode->next=NULL; return numNode; } //新增元素 void addNumNode(NumNode * numNode, int num){ NumNode * node=numNode; while (node->next!=NULL){node=node->next;} NumNode * newNode=(NumNode *)malloc(sizeof(NumNode)); newNode->num=num; newNode->next=NULL; node->next=newNode; } //顯示所有元素 void showAllNum(NumNode *numNode){ NumNode * node=numNode->next; while (node!=NULL){ printf("%d\t",node->num); node=node->next; } } //查詢元素 int findByLastIndex(NumNode * numNode,int lastIndex){ int ct=0; int flag=0; NumNode * numNode1=numNode->next; Queue * queue=creatQueue(); while (numNode1!=NULL){ ct++; if(ct<=lastIndex){ addQueue(queue,numNode1); } else{ flag=1; addQueue(queue,numNode1); DeleteQ(queue); } numNode1=numNode1->next; } if(flag==0){ printf("Not Found\n"); return 0; } else{ printf("Found it. %d\n",queue->Front->next->numNode->num); return 1; } } int main(){ NumNode * numNode=creatNumNode(); for(int i=0;i<10;i++){ addNumNode(numNode,i); } showAllNum(numNode); printf("%d",findByLastIndex(numNode,7)); }

結果
這裡寫圖片描述

錯誤示範(不是最快演算法);

基本思想

定義連結串列
為連結串列新增內容
獲取長度
按長度查詢

實現步驟

  1. 宣告一個連結串列

  2. 做插入操作

  3. 獲取長度實現:
    用while(p->next!=NULL){p=p->next;count++}方式獲取長度

  4. 按索引查詢指定位置實現:
    while(index!=1){p=p->next;index–};

  5. 對索引長度進行封裝:
    關鍵步驟:FindNodeByIndex(node,NodeLength(node)-index+1);正向變逆向查詢

程式碼實現




#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

//定義連結串列
typedef struct _Node * Node;
struct _Node{
    int data;
    Node next;
};
//建立一個連結串列
Node CreatNode(){
    Node node=(Node)malloc(sizeof(struct _Node));
    node->next=NULL;
    return node;
}
//新增一個節點
bool AddNode(Node node,int num){
    Node  p=node;
    while(p->next!=NULL)p=p->next;
    Node newN=(Node)malloc(sizeof(struct _Node));
    newN->data=num;
    newN->next=NULL;
    p->next=newN;
    return true;
}
//獲取連結串列長度
int NodeLength(Node node){
    int length=1;
    Node p=node;
    while (p->next!=NULL){
        p=p->next;
        length++;
    }
    return length;
}
//正向索引查詢
int FindNodeByIndex(Node node, int index){
    Node p=node;
    if(index>NodeLength(node)){
        printf("超出當前長度");
        return 0;
    }
    else{
        while (index!=1){
            p=p->next;
            index--;
        }
    }
    printf("Found it :%d\n",p->data);
    return 1;
}
//逆向查詢
int FindLast(Node node, int last){
    if(FindNodeByIndex(node,NodeLength(node)-last+1)==0){
        return 0;
    }
    else{
        return 1;
    }
}

int main(){
    Node node=CreatNode();
    for(int i=0;i<10;i++){
        AddNode(node,i);
    }
    FindLast(node,2);
    return 0;
}

結果

這裡寫圖片描述