欧美1区2区3区激情无套,两个女人互添下身视频在线观看,久久av无码精品人妻系列,久久精品噜噜噜成人,末发育娇小性色xxxx

【秋招】嵌入式面試八股文 - 數(shù)據(jù)結(jié)構(gòu) 鏈表篇

【秋招】嵌入式面試八股文 - 最全專欄

1. 鏈表基礎(chǔ)概念

Q: 什么是鏈表?鏈表有哪些類型?

鏈表是一種線性數(shù)據(jù)結(jié)構(gòu),由一系列節(jié)點組成,每個節(jié)點包含數(shù)據(jù)字段和指向下一個節(jié)點的引用(指針)。

常見類型:

  • 單向鏈表:每個節(jié)點只有一個指向下一節(jié)點的指針
  • 雙向鏈表:每個節(jié)點有兩個指針,分別指向前一個和后一個節(jié)點
  • 循環(huán)鏈表:最后一個節(jié)點指向第一個節(jié)點,形成環(huán)
  • 雙向循環(huán)鏈表:結(jié)合雙向鏈表和循環(huán)鏈表特性

Q: 鏈表與數(shù)組的區(qū)別是什么?各自的優(yōu)缺點?

區(qū)別與優(yōu)缺點

內(nèi)存分配

動態(tài)分配,不連續(xù)

靜態(tài)分配,連續(xù)空間

隨機訪問

O(n)

O(1)

插入刪除

O(1)(已知位置)

O(n)(需要移動元素)

空間開銷

需要額外指針空間

無額外開銷

緩存局部性

較差

較好

大小調(diào)整

靈活,無需重新分配

固定或需要重新分配

2. 鏈表基本操作

Q: 如何實現(xiàn)單鏈表的創(chuàng)建、插入、刪除和遍歷?

// 定義鏈表節(jié)點結(jié)構(gòu)
typedef struct Node {
    int data;
    struct Node* next;
} Node;

// 創(chuàng)建新節(jié)點
Node* createNode(int data) {
    Node* newNode = (Node*)malloc(sizeof(Node));
    if (newNode == NULL) {
        printf("內(nèi)存分配失敗\n");
        exit(1);
    }
    newNode->data = data;
    newNode->next = NULL;
    return newNode;
}

// 在鏈表頭部插入節(jié)點
Node* insertAtBeginning(Node* head, int data) {
    Node* newNode = createNode(data);
    newNode->next = head;
    return newNode;
}

// 在鏈表尾部插入節(jié)點
Node* insertAtEnd(Node* head, int data) {
    Node* newNode = createNode(data);
    
    // 如果鏈表為空,新節(jié)點就是頭節(jié)點
    if (head == NULL) {
        return newNode;
    }
    
    // 找到最后一個節(jié)點
    Node* temp = head;
    while (temp->next != NULL) {
        temp = temp->next;
    }
    
    // 在最后一個節(jié)點后添加新節(jié)點
    temp->next = newNode;
    return head;
}

// 刪除指定值的節(jié)點
Node* deleteNode(Node* head, int key) {
    // 如果鏈表為空,直接返回
    if (head == NULL) {
        return NULL;
    }
    
    // 如果頭節(jié)點就是要刪除的節(jié)點
    if (head->data == key) {
        Node* temp = head;
        head = head->next;
        free(temp);
        return head;
    }
    
    // 查找要刪除的節(jié)點
    Node* current = head;
    Node* prev = NULL;
    
    while (current != NULL && current->data != key) {
        prev = current;
        current = current->next;
    }
    
    // 如果找到了要刪除的節(jié)點
    if (current != NULL) {
        prev->next = current->next;
        free(current);
    }
    
    return head;
}

// 遍歷鏈表
void traverseList(Node* head) {
    Node* current = head;
    
    while (current != NULL) {
        printf("%d -> ", current->data);
        current = current->next;
    }
    printf("NULL\n");
}

// 釋放鏈表內(nèi)存
void freeList(Node* head) {
    Node* current = head;
    Node* next;
    
    while (current != NULL) {
        next = current->next;
        free(current);
        current = next;
    }
}


Q: 如何實現(xiàn)雙向鏈表的基本操作?

// 定義雙向鏈表節(jié)點結(jié)構(gòu)
typedef struct DNode {
    int data;
    struct DNode* prev;
    struct DNode* next;
} DNode;

// 創(chuàng)建新節(jié)點
DNode* createDNode(int data) {
    DNode* newNode = (DNode*)malloc(sizeof(DNode));
    if (newNode == NULL) {
        printf("內(nèi)存分配失敗\n");
        exit(1);
    }
    newNode->data = data;
    newNode->prev = NULL;
    newNode->next = NULL;
    return newNode;
}

// 在雙向鏈表頭部插入節(jié)點
DNode* insertAtBeginningDLL(DNode* head, int data) {
    DNode* newNode = createDNode(data);
    
    if (head == NULL) {
        return newNode;
    }
    
    newNode->next = head;
    head->prev = newNode;
    return newNode;
}

// 在雙向鏈表尾部插入節(jié)點
DNode* insertAtEndDLL(DNode* head, int data) {
    DNode* newNode = createDNode(data);
    
    if (head == NULL) {
        return newNode;
    }
    
    DNode* temp = head;
    while (temp->next != NULL) {
        temp = temp->next;
    }
    
    temp->next = newNode;
    newNode->prev = temp;
    return head;
}

// 刪除雙向鏈表中的節(jié)點
DNode* deleteNodeDLL(DNode* head, int key) {
    if (head == NULL) {
        return NULL;
    }
    
    // 如果頭節(jié)點是要刪除的節(jié)點
    if (head->data == key) {
        DNode* temp = head;
        head = head->next;
        
        if (head != NULL) {
            head->prev = NULL;
        }
        
        free(temp);
        return head;
    }
    
    DNode* current = head;
    
    while (current != NULL && current->data != key) {
        current = current->next;
    }
    
    if (current == NULL) {
        return head; // 沒找到要刪除的節(jié)點
    }
    
    // 調(diào)整前一個節(jié)點的next指針
    if (current->prev != NULL) {
        current->prev->next = current->next;
    }
    
    // 調(diào)整后一個節(jié)點的prev指針
    if (current->next != NULL) {
        current->next->prev = current->prev;
    }
    
    free(current);
    return head;
}

// 遍歷雙向鏈表
void traverseDLL(DNode* head) {
    DNode* current = head;
    
    printf("NULL <-> ");
    while (current != NULL) {
        printf("%d <-> ", current->data);
        current = current->next;
    }
    printf("NULL\n");
}


3. 鏈表經(jīng)典問題

Q: 如何檢測鏈表中是否有環(huán)?

Floyd的龜兔算法(快慢指針法)

bool hasCycle(Node* head) {
    if (head == NULL || head->next == NULL) {
        return false;
    }
    
    Node* slow = head;
    Node* fast = head;
    
    while (fast != NULL && fast->next != NULL) {
        slow = slow->next;          // 慢指針每次走一步
        fast = fast->next->next;    // 快指針每次走兩步
        
        if (slow == fast) {         // 如果兩個指針相遇,說明有環(huán)
            return true;
        }
    }
    
    return false;  // 如果fast到達鏈表尾部,說明沒有環(huán)
}


Q: 如何找到鏈表的中間節(jié)點?

快慢指針法

Node* findMiddle(Node* head) {
    if (head == NULL) {
        return NULL;
    }
    
    Node* slow = head;
    Node* fast = head;
    
    // 快指針每次走兩步,慢指針每次走一步
    // 當(dāng)快指針到達鏈表尾部時,慢指針恰好在中間
    while (fast != NULL && fast->next != NULL) {
        slow = slow->next;
        fast = fast->next->next;
    }
    
    return slow;  // 慢指針指向中間節(jié)點
}


Q: 如何反轉(zhuǎn)單鏈表?

迭代方法

Node* reverseList(Node* head) {
    Node* prev = NULL;
    Node* current = head;
    Node* next = NULL;
    
    while (current != NULL) {
        next = current->next;    // 保存下一個節(jié)點
        current->next = prev;    // 反轉(zhuǎn)當(dāng)前節(jié)點的指針
        prev = current;          // 移動prev指針
        current = next;          // 移動current指針
    }
    
    return prev;  // 新的頭節(jié)點
}


遞歸方法

Node* reverseListRecursive(Node* head) {
    // 基本情況:空鏈表或只有一個節(jié)點
    if (head == NULL || head->next == NULL) {
        return head;
    }
    
    // 遞歸反轉(zhuǎn)剩余部分
    Node* newHead = reverseListRecursive(head->next);
    
    // 改變指針方向
    head->next->next = head;
    head->next = NULL;
    
    return newHead;
}


Q: 如何合并兩個有序鏈表?

Node* mergeTwoLists(Node* l1, Node* l2) {
    // 創(chuàng)建一個啞節(jié)點作為合并鏈表的頭部
    Node dummy;
    Node* tail = &dummy;
    
    while (l1 != NULL && l2 != NULL) {
        if (l1->data <= l2->data) {
            tail->next = l1;
            l1 = l1->next;
        } else {
            tail->next = l2;
            l2 = l2->next;
        }
        tail = tail->next;
    }
    
    // 連接剩余部分
    if (l1 != NULL) {
        tail->next = l1;
    } else {
        tail->next = l2;
    }
    
    return dummy.next;
}


Q: 如何檢測并找到環(huán)的入口點?

Node* detectCycleStart(Node* head) {
    if (head == NULL || head->next == NULL) {
        return NULL;
    }
    
    Node* slow = head;
    Node* fast = head;
    bool hasCycle = false;
    
    // 第一步:檢測是否有環(huán)
    while (fast != NULL && fast->next != NULL) {
        slow = slow->next;
        fast = fast->next->next;
        
        if (slow == fast) {
            hasCycle = true;
            break;
        }
    }
    
    if (!hasCycle) {
        return NULL;
    }
    
    // 第二步:找到環(huán)的入口點
    slow = head;
    while (slow != fast) {
        slow = slow->next;
        fast = fast->next;
    }
    
    return slow;  // 環(huán)的入口點
}


4. 高級鏈表問題

Q: 如何判斷兩個鏈表是否相交?如何找

剩余60%內(nèi)容,訂閱專欄后可繼續(xù)查看/也可單篇購買

雙非本,211碩。本碩均為機械工程,自學(xué)嵌入式,在校招過程中拿到小米、格力、美的、比亞迪、海信、???、大華、江波龍等offer。八股文本質(zhì)是需要大家理解,因此里面的內(nèi)容一定要詳細、深刻!這個專欄是我個人的學(xué)習(xí)筆記總結(jié),是對很多面試問題進行的知識點分析,專欄保證高質(zhì)量,讓大家可以高效率理解與吸收里面的知識點!掌握這里面的知識,面試絕對無障礙!

全部評論

相關(guān)推薦

評論
點贊
收藏
分享

創(chuàng)作者周榜

更多
??途W(wǎng)
牛客企業(yè)服務(wù)