【轉】頭插法和尾插法


HashMap在JDK1.8為什么改用使用尾插法

因為 1.7頭插法擴容時,頭插法會使鏈表發生反轉,多線程環境下會產生環;
A 線程在插入節點 B,B 線程也在插入,遇到容量不夠開始擴容,重新 hash,放置元素,采用頭插法,后遍歷到的 B 節點放入了頭部,這樣形成了環。

1、假設容器大小為2,數組0 的鏈表上初始有個 A節點。A線程和B線程同時插入B節點。

2、B線程cup占用、頭指針指向A節點后 cup被A線程占用。

3、A線程插入節點B時,剛好hash 到數組0,則該鏈表 為  B —>  A。

4、B線程 插入節點B時,發現內存不夠,進行resize擴容操作,恰巧節點rehash后也是在同一個位置上。該方法實現的機制就是將每個鏈表轉化到新鏈表,並且鏈表中的位置發生反轉(鏈表轉置)。現在為 A —> B。

 5、B實現插入節點B操作后就形成了環。

 以上參考自:https://blog.csdn.net/weixin_42373997/article/details/112085344?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_baidulandingword-0&spm=1001.2101.3001.4242https://blog.csdn.net/csdn_1107/article/details/108236495

 

以下轉載自:https://blog.csdn.net/qq_40938077/article/details/80216563

方法1:頭插法

基本思路:

定義一個鏈表類型的指針l,指針l指向的是鏈表的首地址,而不是鏈表的第一個數,指針l指向的下一個鏈表類型才是鏈表的第一個數,每次往鏈表中加數都加到鏈表中的第1個位置(即指針l指向的位置)。

代碼:

最好自己看代碼在紙上模擬一下過程

#include<bits/stdc++.h>
using namespace std
typedef struct Node
{
    int value;
    struct Node *next;
}node,*linkedlist;
linkedlist linkedlistcreath()//返回的是該鏈表的地址
{
    node *l=(node*)malloc(sizeof(node));
    l->next=NULL;
    int number;
    while (scanf("%d",&number)!=EOF)
    {
        node *p=(node*)malloc(sizeof(node));//新建一個node結構並為其申請空間
        p->value=number;//給新建的node結構賦值
        p->next=l->next;//賦值p所指的節點(就是l所指的節點,即鏈表的第2個節點)
        l->next=p;//將l所指的節點更新為p點
    }
    return l;//返回頭節點地址
 
}

方法2:尾插法

基本思路:

還是先定義一個鏈表類型的指針l,指針l指向的是鏈表的首地址,而不是鏈表的第一個數,指針l指向的下一個鏈表類型才是鏈表的第一個數,然后定義一個r指針,保證r指針始終指向鏈表的最后一個位置上的節點,然后讓新加的節點加入到r指針指向的節點的后面。

代碼如下:

最好自己看代碼在紙上模擬一下過程

#include<bits/stdc++.h>
using namespace std;
typedef struct Node
{
    int value;
    struct Node *next;
} node,*linkedlist;
linkedlist linkedlistcreatt()//返回的是該鏈表的地址
{
    node *l=(node*)malloc(sizeof(node));
    l->next=NULL;
    node *r;//r指向的始終是該鏈表的最后一個node結構
    r=l;//這個地方是地址之間的賦值,所以對r操作就相當於對l操作,即對鏈表最后一個node結構操作
    int number;
    while (scanf("%d",&number)!=EOF)
    {
        node *p=(node*)malloc(sizeof(node));//新建一個node結構並為其申請空間
        p->value=number;//給新建的node結構賦值
        r->next=p;//將p插入到鏈表的最后一個node結構的后面
        p->next=NULL;//此時p已經是鏈表的最后一個了,給p的next賦值
        r=p;//讓r等於鏈表的最后一個node結構,即p節點
    }
    return l;//返回頭節點的地址
 
}

 

轉載:https://blog.csdn.net/qq_40938077/article/details/80216563


免責聲明!

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



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