Implementation of Singly-Linked List in C++

  1. 这篇文章并不解释“链表是什么”;我们的重心是“链表如何用c++实现”;
  2. 由于我没有画图,所以在看这篇文章之前,我希望读者已经对链表的定义有了一个粗略的了解。可以谷歌 "singly-linked list visualization"。

单向链表是数据结构的第一课。虽然是无比简单的内容,但如果不能对链表有一个非常清晰的理解,后面的学习会变得十分痛苦。所以我想花点儿时间在链表的代码实现上。先人画了无数张图,摆事实讲道理,来帮我们理解链表的操作。然而对图的理解如果不能落实到代码上,再好也是空中楼阁。

先用c++写一个简单的链表实现:

struct Node{
    int val;
    Node *next;
};

在c++中,最简单的实现链表的方法就是结构体。著名的OJ,LeetCode,对链表的定义是这样的:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */

作为一只小白,我没能理解最后一句"ListNode(int x) : val(x), next(NULL) {}",不过我猜是构造函数什么的。等我学明白了再回来补坑~

当我们获得了一只结构体用来作为链表的数据类型,我们就可以开始创建这个链表啦:

Node *create(){ //返回值是Node类型的指针,也就是head
    Node *head, *temp; int num, n; 
    //new运算符用以获得一片用来存放一个Node类型变量的存储空间,并且把这片存储空间的地址赋给head
    head = new Node; temp = head;  
    cin>>num;
    while(num != -1){
        n++;
        temp->val = num;
        //c++中,如果我们需要动态地申请新的内存空间,记得一定要用new运算符
        temp->next = new Node;
        temp = temp->next;
        cin>>num;
    }
    if (n==0) head = NULL; else temp->next = NULL;
    return head;
}

因为自己曾经为Node *create()这条语句困惑过,所以这里想解释一下另一个知识点:指针作为函数返回值。

函数的返回值可以是多种类型:
  1. 返回int类型的函数:
    int function (int x, int y);
  2. 返回指针类型数据的函数:
    int *function (int x, int y);
    -- 函数名字前面表示函数的类型 “*”

所以Node *create()就代表这个函数会返回一个Node类型的指针,也就是head。

接下来,链表的遍历:

Node *pointer = create();
while(pointer->next != NULL){
    cout<<pointer->val<<endl;
    pointer = pointer->next;
}

链表的删除需要分两种情况讨论:

  1. 链表为空(极端情况,任何时候都要考虑到);
  2. 待删除节点是链表的头结点;
  3. 带删除节点不是头结点。

所以我们需要两个指针,一个指向待删除节点,一个指向该节点前一个节点。当我们要删除当前节点时,直接把待删除节点的next赋给前一个节点的next。赋值之后,前一个节点的next就会指向待删除节点的next,也就是说待删除节点在这条链表中,已经不存在了。
(这个过程如果用语言来表述,会显得有点儿复杂。建议大家还是去找图看,然后再配合代码来理解。如果能自己动手敲一敲,相信会有更加深刻的体会。)

Node *dele(Node *head, int n){
    Node *temp, *follow;
    temp = head;
    if (head == NULL) return head;
    if (head->val == n){
        head = head->next;
        delete temp;
    }
    while (temp!= NULL && temp->val != n){
        follow = temp;
        temp = temp->next;
    }
    if (temp == NULL) cout<<"Not Found";
    else{
        follow->next = temp->next;
        delete temp;
    }
    return head;
}

添加新节点的话,也同样需要分情况讨论:

  1. 链表为空,则把新节点unit赋给head就好;
  2. 新节点是链表的第一个节点;
  3. 新节点是链表最后一个节点;
  4. 新节点在链表中间。

小心哦,极端情况都有可能成为竞赛以及面试中的超级大坑_(:зゝ∠)。
代码如下:

Node *insert(Node *head, int n){
    Node *temp, *follow, *unit;
    temp = head;
    unit = new Node; unit->val = n; unit->next = NULL; 
    if (head == NULL){ //情况1:空链表,则设新节点为head并返回
        head = unit;
        return head;
    }
//这里我们自动默认链表是sorted了,如果有别的情况要自己写合法判断哦。
    while((temp->next != NULL) && (temp->val < n)){  //找到需要添加新节点的位置
        follow = temp;
        temp = temp->next;
    }
    if(temp == head){ //情况2:要插入的节点会是新的头结点
        unit->next = head;
        head = unit;
    }
    else{
        if(temp->next == NULL) temp->next = unit; // 情况3:新节点是尾节点
        else { //情况4:新节点在链表的中间
            unit->next=temp;
            follow->next=unit;
        }
    }
    return head;
}

就酱,我滚去继续敲doubly-linked list辣 ( _ )/~~


参考资料:
  • LeetCode Online Judge
  • 北京大学良心网课:C程序设计进阶 (稍微安利一发,个人很喜欢李戈老师老师的讲课风格。可谓“谈笑间,樯橹灰飞烟灭”:信手拈来,层层深入,妙趣横生又获益无穷。)
  • UCSD良心网课:Data Structures
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,084评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,623评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,450评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,322评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,370评论 6 390
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,274评论 1 300
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,126评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,980评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,414评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,599评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,773评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,470评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,080评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,713评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,852评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,865评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,689评论 2 354

推荐阅读更多精彩内容