0.目录

1.链表的基本操作

2.结点的基本操作

3.面试题

1.链表的基本操作

1.1 结点定义

#include <iostream>

using namespace std;

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

1.2 创建链表

Node* createLinkedList(int data[], int len)
{
Node* ret = NULL;
Node* slider = NULL; for(int i=0; i<len; i++)
{
Node* n = new Node(); n->value = data[i];
n->next = NULL; if( slider == NULL )
{
slider = n;
ret = n;
}
else
{
slider->next = n;
slider = n;
}
} return ret;
}

1.3 销毁链表

void destroyLinkedList(Node* list)
{
while( list )
{
Node* del = list; list = list->next; delete del;
}
}

1.4 打印链表

void printLinkedList(Node* list)
{
while( list )
{
cout << list->value << "->"; list = list->next;
} cout << "NULL" << endl;
}

1.5 获取链表长度

int getListLength(Node* list)
{
int ret = 0; while( list )
{
ret++;
list = list->next;
} return ret;
}

测试:

int main()
{
int a[] = {1, 5, 3, 2, 4}; Node* list1 = createLinkedList(a, 5);
printLinkedList(list1);
cout << getListLength(list1) << endl;
destroyLinkedList(list1);
cout << endl; Node* list2 = createLinkedList(NULL, 0);
printLinkedList(list2);
cout << getListLength(list2) << endl;
destroyLinkedList(list2);
cout << endl; int b[] = {6};
Node* list3 = createLinkedList(b, 1);
printLinkedList(list3);
cout << getListLength(list3) << endl;
destroyLinkedList(list3); return 0;
}

运行结果为:

1->5->3->2->4->NULL
5 NULL
0 6->NULL
1

2.结点的基本操作

2.1 删除结点

Node* deleteNode(Node* list, int value)
{
Node* head = list;
Node* slider = NULL; while( head && (head->value == value) )
{
slider = head;
head = head->next;
slider = NULL;
} Node* ret = head; while( ret )
{
slider = ret->next; if( slider && (slider->value == value) )
{
ret->next = slider->next;
slider = NULL;
}
else
{
ret = ret->next;
}
} return head;
}

测试:

int main()
{
int a[] = {1, 2, 3, 2, 5}; Node* list1 = createLinkedList(a, 5);
printLinkedList(list1);
printLinkedList(deleteNode(list1, 2));
destroyLinkedList(list1);
cout << endl; Node* list2 = createLinkedList(NULL, 0);
printLinkedList(list2);
printLinkedList(deleteNode(list2, 2));
destroyLinkedList(list2);
cout << endl; int b[] = {2, 2, 2, 2, 2};
Node* list3 = createLinkedList(b, 5);
printLinkedList(list3);
printLinkedList(deleteNode(list3, 2));
destroyLinkedList(list3);
cout << endl; int c[] = {1};
Node* list4 = createLinkedList(c, 1);
printLinkedList(list4);
printLinkedList(deleteNode(list4, 2));
destroyLinkedList(list4); return 0;
}

运行结果为:

1->2->3->2->5->NULL
1->3->5->NULL NULL
NULL 2->2->2->2->2->NULL
NULL 1->NULL
1->NULL

2.2 查找结点

Node* findNode(Node* list, int value)
{
Node* ret = NULL;
Node* slider = list; while( slider )
{
if( slider->value == value )
{
ret = slider;
break;
}
else
{
slider = slider->next;
}
} return ret;
}

3.面试题

3.1 反转链表

Node* reverseLinkedList(Node* list)
{
Node* ret = NULL;
Node* slider = list;
Node* next = NULL; while( slider )
{
next = slider->next;
slider->next = ret;
ret = slider;
slider = next;
} return ret;
}

测试:

int main()
{
int a[] = {1, 5, 3, 2, 4}; Node* list1 = createLinkedList(a, 5);
printLinkedList(list1);
printLinkedList(reverseLinkedList(list1));
destroyLinkedList(list1);
cout << endl; Node* list2 = createLinkedList(NULL, 0);
printLinkedList(list2);
printLinkedList(reverseLinkedList(list2));
destroyLinkedList(list2);
cout << endl; int b[] = {6};
Node* list3 = createLinkedList(b, 1);
printLinkedList(list3);
printLinkedList(reverseLinkedList(list3));
destroyLinkedList(list3); return 0;
}

运行结果为:

1->5->3->2->4->NULL
4->2->3->5->1->NULL NULL
NULL 6->NULL
6->NULL

3.2 合并两个单向排序链表

Node* mergeLinkedList(Node* list1, Node* list2)
{
Node* ret = NULL; if( list1 == NULL )
{
ret = list2;
}
else if( list2 == NULL )
{
ret = list1;
}
else
{
if( list1->value < list2->value )
{
ret = list1;
list1 = list1->next;
}
else
{
ret = list2;
list2 = list2->next;
} Node* slider = ret; while( list1 && list2 )
{
if( list1->value < list2->value )
{
slider->next = list1;
list1 = list1->next;
}
else
{
slider->next = list2;
list2 = list2->next;
} slider = slider->next;
} if( list1 == NULL )
{
slider->next = list2;
}
else if( list2 == NULL )
{
slider->next = list1;
}
} return ret;
}

测试:

int main()
{
int a[] = {1, 2, 4, 6, 8}; Node* list1 = createLinkedList(a, 5);
printLinkedList(list1); int b[] = {2, 2, 3, 3, 7};
Node* list2 = createLinkedList(b, 5);
printLinkedList(list2); Node* list3 = mergeLinkedList(list1, list2);
printLinkedList(list3);
destroyLinkedList(list3); return 0;
}

运行结果为:

1->2->4->6->8->NULL
2->2->3->3->7->NULL
1->2->2->2->3->3->4->6->7->8->NULL

3.3 查找两个链表的第一个公共结点

Node* findFirstCommonNode(Node* list1, Node* list2)
{
int len1 = getListLength(list1);
int len2 = getListLength(list2);
Node* ret = NULL; if( len1 > len2 )
{
for(int i=0; i<(len1-len2); i++)
{
list1 = list1->next;
}
}
else
{
for(int i=0; i<(len2-len1); i++)
{
list2 = list2->next;
}
} while( list1 )
{
if( list1 == list2 )
{
ret = list1;
break;
}
else
{
list1 = list1->next;
list2 = list2->next;
}
} return ret;
}

测试:

int main()
{
int a[] = {1, 2, 3};
Node* list1 = createLinkedList(a, 3); int b[] = {4, 5};
Node* list2 = createLinkedList(b, 2); int c[] = {6, 7};
Node* list3 = createLinkedList(c, 2); Node* ret = NULL; ret = list1;
while( ret->next )
{
ret = ret->next;
}
ret->next = list3; ret = list2;
while( ret->next )
{
ret = ret->next;
}
ret->next = list3; printLinkedList(list1);
printLinkedList(list2); ret = findFirstCommonNode(list1, list2);
printLinkedList(ret); return 0;
}

运行结果为:

1->2->3->6->7->NULL
4->5->6->7->NULL
6->7->NULL

3.4 删除排序链表中重复的结点

Node* deleteDuplicationNode(Node* list)
{
Node* head = list;
Node* toDel = NULL;
Node* end = NULL; // 处理头结点重复的情况
while( head && head->next && (head->value == head->next->value) )
{
end = head;
// 找到最后一个与头结点重复的结点
while( end && end->next && (end->value == end->next->value) )
{
end = end->next;
}
// 删除中间与头结点重复的结点
while( head != end )
{
toDel = head;
head = head->next;
toDel = NULL;
}
// 删除最后一个与头结点重复的结点
toDel = head;
head = head->next;
toDel = NULL;
} Node* ret = head;
Node* slider = NULL; while( ret && ret->next )
{
slider = ret->next; // 处理中间结点重复的情况
while( slider && slider->next && (slider->value == slider->next->value) )
{
end = slider;
// 找到最后一个与中间结点重复的结点
while( end && end->next && (end->value == end->next->value) )
{
end = end->next;
}
// 删除中间与中间结点重复的结点
while( slider != end )
{
toDel = slider;
slider = slider->next;
toDel = NULL;
}
// 删除最后一个与中间结点重复的结点
toDel = slider;
slider = slider->next;
ret->next = slider;
toDel = NULL;
} if( ret->next == slider )
{
ret = ret->next;
}
else
{
ret->next = slider;
}
} return head;
}

测试:

int main()
{
int a[] = {1, 1, 1, 2, 2, 2, 3, 4, 4, 4, 5, 5}; Node* list1 = createLinkedList(a, 12);
printLinkedList(list1);
printLinkedList(deleteDuplicationNode(list1));
destroyLinkedList(list1);
cout << endl; Node* list2 = createLinkedList(NULL, 0);
printLinkedList(list2);
printLinkedList(deleteDuplicationNode(list2));
destroyLinkedList(list2);
cout << endl; int b[] = {2, 3, 3, 3, 4, 4, 5, 6, 6, 7};
Node* list3 = createLinkedList(b, 10);
printLinkedList(list3);
printLinkedList(deleteDuplicationNode(list3));
destroyLinkedList(list3);
cout << endl; int c[] = {1};
Node* list4 = createLinkedList(c, 1);
printLinkedList(list4);
printLinkedList(deleteDuplicationNode(list4));
destroyLinkedList(list4); return 0;
}

运行结果为:

1->1->1->2->2->2->3->4->4->4->5->5->NULL
3->NULL NULL
NULL 2->3->3->3->4->4->5->6->6->7->NULL
2->5->7->NULL 1->NULL
1->NULL

关于链表的总结(C++循环实现)的更多相关文章

  1. Linked List Cycle 判断一个链表是否存在回路(循环)

    Given a linked list, determine if it has a cycle in it. Follow up:Can you solve it without using ext ...

  2. leetcode206 反转链表 两种做法(循环,递归)

    反转链表 leetcode206 方法1 循环 public ListNode reverseList(ListNode head) { if (head == null || head.next = ...

  3. 剑指Offer面试题:4.从尾到头打印链表

    一.题目:从尾到头打印链表 题目:输入一个链表的头结点,从尾到头反过来打印出每个结点的值. 到解决这个问题肯定要遍历链表.遍历的顺序是从头到尾的顺序,可输出的顺序却是从尾到头.也就是说第一个遍历到的结 ...

  4. JAVA 链表操作:循环链表

    主要分析示例: 一.循环链表简述 二.单链表循环链表 三.双链表循环链表 一.循环链表简述 循环链表即链表形成了一个循环的结构,尾节点不再指向NULL,而是指向头节点HEAD,此时判定链表的结束是尾节 ...

  5. C语言链表各类操作详解

    链表概述 链表是一种常见的重要的数据结构.它是动态地进行存储分配的一种结构.它可以根据需要开辟内存单元.链表有一个“头指针”变量,以head表示,它存放一个地址.该地址指向一个元素.链表中每一个元素称 ...

  6. 链表插入排序(insertion-sort-list)

    自己写的代码有几个比较大的用例一直过不去,网上的代码大部分有问题,思路是先将链表置空表,再将链表中的元素循环插入到指定位置. 下面是一份正确的代码,但是是带头节点的链表: void Insertsor ...

  7. linux内核数据结构之链表

    linux内核数据结构之链表 1.前言 最近写代码需用到链表结构,正好公共库有关于链表的.第一眼看时,觉得有点新鲜,和我之前见到的链表结构不一样,只有前驱和后继指针,而没有数据域.后来看代码注释发现该 ...

  8. C/C++中对链表操作的理解&&实例分析

    链表概述 链表是一种常见的重要的数据结构.它是动态地进行存储分配的一种结构.它可以根据需要开辟内存单元.链表有一个“头指针”变量,以head表示,它存放一个地址.该地址指向一个元素.链表中每一个元素称 ...

  9. C/C++ 知识点---链表操作

    1.单链表单链表的结点类型node定义: typedef struct linknode { int data; struct linknode *node; }node; <1>.建立单 ...

  10. 数据结构——Java实现单链表

    一.分析 单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素.链表中的数据是以结点来表示的,每个结点由元素和指针构成.在Java中,我们可以将单链表定义成一个类,单链表的基 ...

随机推荐

  1. day51

    JS基础操作 一.分支结构 1.if语句 if 基础语法 if (条件表达式) { 代码块; } // 当条件表达式结果为true,会执行代码块:反之不执行 // 条件表达式可以为普通表达式 // 0 ...

  2. 解决EF使用context.Database.SqlQuery时NotMapped属性列为空null的问题(转载)

    有时候我们要为EF中的Model加一个新属性,这个属性不是数据库中的字段,而是从其它表中关联出来的.EF中要标示一个列不是对应表中字段只需要加上NotMapped特性.要使用NotMapped,保证你 ...

  3. 算法篇(前序)——Java的集合

    菜鸟拙见,望请纠正:附上JDK参考文档(中文文档和英文文档):链接:https://pan.baidu.com/s/14KDmCtQxeGCViq7e0zENjA 密码:e9xs  以及算法篇全文链接 ...

  4. adr adrl ldr mov总结整理

    ADR这是一条小范围的地址读取伪指令,它将基于PC的相对偏移的地址值读到目标寄存器中.     使用的格式:ADR register,exper.     在编译源程序时,汇编器首先计算出当前PC值( ...

  5. 分享一下个人学PS的过程

    得知Photoshop这款软件是在上大学的时候,2010年.学校学生会的科技部纳新,要求新人会PPT.word.Excel和Photoshop.当时有一个Photoshop大神,成为了学生会科技部的主 ...

  6. Unity特殊路径

    Resources: Resources文件可以在根目录下,也可以在子目录下,只要叫Resources就好.Resources目录下所有资源将被打包进游戏存放资源的archive中,Resources ...

  7. 由Windows开发平台向Linux平台转移的一些想法

    从毕业到现在已经快20年了,一直在从事Windows平台上的开发工作.刚毕业那会大约是97,98年左右,工作的平台除了Windows平台还有Dos平台,因为在学校学习时,也是从Dos开始的.因此对于从 ...

  8. 英国诗人乔叟Dethe is my Finaunce金融

    英国诗人乔叟Dethe is my Finaunce金融 英语中“金融”在14世纪,金融计算时间价值的手段.就随机结果签约的能力.一个允许转让金融权后的清算.<Lamentation of Ma ...

  9. django反向解析URL和URL命名空间

    django反向解析URL和URL命名空间 首先明确几个概念: 1.在html页面上的内容特别是向用户展示的url地址,比如常见的超链接,图片链接等,最好能动态生成,而不要固定. 2.一个django ...

  10. Beta阶段对团队成员公开感谢

    我感谢付佳对我的帮助,因为Beta阶段她承担了一名组长责任,每次代码编写,安排任务都由她带头来做,并且在代码方面帮助我解决了一些问题.