数据结构算法——链表的各种操作,C++和Python
时隔已久,一直没更新博客,感觉很愧疚呀。
先贴上所有的代码。这个是用C++写的
#include "stdafx.h" //Author:Albert
//Date: 2018.10.28 #include<iostream>
using namespace std; typedef int datatype;
class Node
{
public:
int data;
Node *next;
}; class linkList
{
public:
linkList();//初始化一个单链表
~linkList();//销毁一个单链表
bool creatLinkListByInput(int n);//通过控制台输入新建一个长度为n的单链表
void dispLinkList();//把链表里储存的数据都显示出来
int getLength();
void insertNodetoEnd(datatype data);
void insertNode(datatype data, int n);//在第n个数据后插入一个数据data
void DeleteNode(int n);//删除第n个节点
void Reverse();
private:
Node * head;
}; linkList::linkList()
{
head = new Node;
head->data = ;
head->next = NULL;
}
linkList::~linkList()
{
delete head;
}
bool linkList::creatLinkListByInput(int n)
{
Node *pnew, *ptemp;
ptemp = head;
if (n < ) { cout << "error" << endl; return false; }
for (int i = ;i < n;i++)
{
pnew = new Node;
cout << "请输入第" << i + << "个值:";
cin >> pnew->data;
pnew->next = NULL;
ptemp->next = pnew;
ptemp = pnew;
}
return true;
}
void linkList::dispLinkList()
{
Node *p;
p = head;
if (p!=NULL)
{
while (p->next!=NULL)
{
p = p->next;
cout << p->data << endl;
}
}
else
{
cout << "这是一个空链表" << endl;
}
} int linkList::getLength()
{
int n=;
Node *p;
p = head;
while (p->next!=NULL)
{
n++;
p = p->next;
}
return n;
} void linkList::insertNodetoEnd(datatype data)
{
Node *pnew=new Node;
pnew->data = data;
pnew->next = NULL; Node *p=head;
while (p->next != NULL)
{
p = p->next;
}
p->next = pnew;
} void linkList::insertNode(datatype data, int n)
{
Node *p = head;
Node *pnew = new Node;
for (int i = ;i < n;i++)
{
p = p->next;
}
//此时p指向的是第n个数据
pnew->data = data;
pnew->next = p->next;
p->next = pnew;
} void linkList::DeleteNode(int n)
{
Node *p = head;
Node *ppre = new Node;
for (int i = ;i < n;i++)
{
ppre = p;
p = p->next;
}
//ppre是要删除的节点的前一个节点
ppre->next = p->next;
delete p;
} void linkList::Reverse()
{ Node *plast = head->next;
Node *p = plast->next;
Node *ptmp = new Node;
plast->next = NULL;
while (p->next != NULL)
{
ptmp = p;
p = p->next;
ptmp->next = plast;
plast= ptmp;
}
p->next = plast;
head->next = p;
} int main()
{
linkList a; //新建一个长度为3的单链表
a.creatLinkListByInput();
a.dispLinkList();
cout << "链表长度为:" << a.getLength() << endl; cout << "在尾部插入一个1:" << endl;
a.insertNodetoEnd();
a.dispLinkList();
cout << "链表长度为:" << a.getLength() << endl; cout << "在第2个数据后插入1:" << endl;
a.insertNode(,);
a.dispLinkList();
cout << "链表长度为:" << a.getLength() << endl; cout << "删除第4个数据" << endl;
a.DeleteNode();
a.dispLinkList();
cout << "链表长度为:" << a.getLength() << endl; cout << "将链表逆置" << endl;
a.Reverse();
a.dispLinkList(); return ;
}
1、新建一个单链表
bool linkList::creatLinkListByInput(int n)
{
Node *pnew, *ptemp;
ptemp = head;
if (n < ) { cout << "error" << endl; return false; }
for (int i = ;i < n;i++)
{
pnew = new Node;
cout << "请输入第" << i + << "个值:";
cin >> pnew->data;
pnew->next = NULL;
ptemp->next = pnew;
ptemp = pnew;
}
return true;
}
这个代码还是我看了别人的之后才写的。在控制台输入一系列数据,返回是否新建成功。
其中最关键的一处就是定义一个head节点。这个节点不储存数据,head->next才是第一个储存的数据。
这样的话就比较好写循环里的内容了,后面的调用也很方便。
用图画一下就很容易理解了。
显示整个链表数据,得到链表长度什么的,不用多说啦。直接遍历就行。
2、插入节点。
void linkList::insertNode(datatype data, int n)
{
Node *p = head;
Node *pnew = new Node;
for (int i = ;i < n;i++)
{
p = p->next;
}
//此时p指向的是第n个数据
pnew->data = data;
pnew->next = p->next;
p->next = pnew;
}
先遍历到到第n个节点
然后
3、删除一个节点
void linkList::DeleteNode(int n)
{
Node *p = head;
Node *ppre = new Node;
for (int i = ;i < n;i++)
{
ppre = p;
p = p->next;
}
//ppre是要删除的节点的前一个节点
ppre->next = p->next;
delete p;
}
把它画出来就是
4、单链表的逆置
void linkList::Reverse()
{ Node *plast = head->next;
Node *p = plast->next;
Node *ptmp = new Node;
plast->next = NULL;
while (p->next != NULL)
{
ptmp = p;
p = p->next;
ptmp->next = plast;
plast= ptmp;
}
p->next = plast;
head->next = p;
}
这里ptmp的作用就是为了防止p->next=plast从而导致无法往下遍历。
我见还有一种用ppre,p,pnex三个指针的。思想跟这个差不多。
感觉自己菜的要死,只能从头再开始学啦。
还有几个问题
链表中环的检测:用的快慢指针的思想。
两个有序链表的合并:遍历,主要是别让指针指乱了。
删除链表倒数第n个节点。如果链表长度知道,就很简单了,转化为整数就好。如果长度不知道,我觉得,就用迭代可以有。
求链表中的中间节点,用快慢针呀。
这几个问题我没时间一个一个的写啦。以后遇到了在一个一个的写。
此外还有循环链表和双向链表,他们都各有千秋,懂的单链表,这都很简单了。
以下为我看了Python写的之后的追加
最近贼以下把它封装成一个类,嘿嘿嘿。面向对象编程感觉条理贼清晰
#!/user/bin/python3
# -*- coding:utf- -*-
#@author:Albert
#@time:// class Node(object):
def __init__(self,x):
self.data=x
self.next=None class Linklist():
def __init__(self,l):
self.head=Node()
self.changeLinklistTo(l)
def changeLinklistTo(self,l):
p=self.head
for i in l:
p.next=Node(i)
p=p.next
def display(self):
p=self.head.next
while(p):
print(p.data)
p=p.next
def reverse(self):#翻转整个链表
cur,prev=self.head.next,None
while cur:
cur.next,prev,cur=prev,cur,cur.next
self.head.next=prev
def swapPairs(self):#交换相邻的两个链表节点位置
pre=self.head
while pre.next and pre.next.next:
a=pre.next
b=pre.next.next
pre.next,b.next,a.next=b,a,b.next #此处多重赋值是先计算右边,然后统一赋给左边
pre=a
def hasCycle(self):#检测单链表环,用的快慢针的思想
fast=slow=self.head.next
while fast and slow and fast.next:
slow=slow.next
fast=fast.next.next
if fast is slow:
return True
return False
a=Linklist([,,,,,])
a.display()
a.reverse()
print("A has been reversed")
a.display()
a.swapPairs()
print("A has been swapped")
a.display() print("A has cycle? : ",a.hasCycle())
数据结构算法——链表的各种操作,C++和Python的更多相关文章
- c语言,数据结构,链表的一些操作总结
下面是自己的一些学习操作以及总结,能用我会很开心,有不足之处,欢迎大家提出宝贵的意见! c语言链表是一种基本的数据结构,与顺序表一样属于线性表,但是顺序表在内存中的存储单元是连续的,这样就对内存的要求 ...
- 数据结构与算法 —— 链表linked list(01)
链表(维基百科) 链表(Linked list)是一种常见的基础数据结构,是一种线性表,但是并不会按线性的顺序存储数据,而是在每一个节点里存到下一个节点的指针(Pointer).由于不必须按顺序存储, ...
- 数据结构之链表-链表实现及常用操作(C++篇)
数据结构之链表-链表实现及常用操作(C++篇) 0.摘要 定义 插入节点(单向链表) 删除节点(单向链表) 反向遍历链表 找出中间节点 找出倒数第k个节点 翻转链表 判断两个链表是否相交,并返回相交点 ...
- JavaScript数据结构与算法-链表练习
链表的实现 一. 单向链表 // Node类 function Node (element) { this.element = element; this.next = null; } // Link ...
- C语言数据结构-单链表的实现-初始化、销毁、长度、查找、前驱、后继、插入、删除、显示操作
1.数据结构-单链表的实现-C语言 typedef struct LNode { int data; struct LNode* next; } LNode,*LinkList; //这两者等价.Li ...
- python算法与数据结构-单链表(38)
一.链表 链表是一种物理存储单元上非连续.非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的.链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成.每个结点包括 ...
- Java实现 蓝桥杯VIP 算法训练 链表数据求和操作
算法训练 9-7链表数据求和操作 时间限制:1.0s 内存限制:512.0MB 读入10个复数,建立对应链表,然后求所有复数的和. 样例输入 1 2 1 3 4 5 2 3 3 1 2 1 4 2 2 ...
- 算法 - 链表操作思想 && case
算法 - 链表操作题目套路 前面这一篇文章主要讲链表操作时候的实操解决方式,本文从本质讲解链表操作的元信息,学完后,再也不怕链表操作题目了. 1.链表的基本操作 链表的基本操作无外乎插入,删除,遍历 ...
- 数据结构算法集---C++语言实现
//数据结构算法集---C++语言实现 //各种类都使用模版设计,可以对各种数据类型操作(整形,字符,浮点) /////////////////////////// // // // 堆栈数据结构 s ...
随机推荐
- 汇编:jmp系列跳转指令总结
助记方法: J:跳转C: 进位位置位N: 否S: 符号位置位o: 溢出位置位Z: 零标志位置位E: 等于P:奇偶位置位A: AboveB: BelowL: Less (Little的比较级)G: Gr ...
- Win 10 Google 云端硬盘 网页证书问题导致无法登录解决办法
操作方法 按照图示,将以下3项勾去并确定. 效果 设置以后,可成功访问:
- 【总结】Oracle sql 中的字符(串)替换与转换
1.REPLACE 语法:REPLACE(char, search_string,replacement_string) 用法:将char中的字符串search_string全部转换为字符串repla ...
- SPOJ - MATSUM Matrix Summation---二维树状数组
题目链接: https://vjudge.net/problem/SPOJ-MATSUM 题目大意: 二维数组,两种操作 SET 将某点设置成x SUM 求某个区域之和 解题思路: 这里用二维树状数组 ...
- CopyOnWriteArrayList分析——能解决什么问题
CopyOnWriteArrayList主要可以解决的问题是并发遍历读取无锁(通过Iterator) 对比CopyOnWriteArrayList和ArrayList 假如我们频繁的读取一个可能会变化 ...
- 阿里云服务器下安装LAMP环境(CentOS Linux 6.3) 安装与配置 Apache 服务
想让我们的阿里云服务器成为一台 Web 服务器,我们需要安装一个 Web 服务器软件,比如 Apache ,或者 Nginx 等等.下面我们就一起来安装一个 Apache 服务. 我们可以使用 yum ...
- InstallShield Limited Edition for Visual Studio 2013 图文教程打包安装包
http://www.wuleba.com/23892.html 从Visual Studio 2012开始,微软就把自家原来的安装与部署工具彻底废掉了,转而让大家去安装使用第三方的打包工具“Inst ...
- JSPatch - iOS 动态补丁
JSPatch库,支持在线更新iOS应用,目前BDN项目中有用到,主要用来修复线上Crash和Bug 相关博文推荐: JSPatch – 动态更新iOS APP(这是JSPatch作者的博文) JSP ...
- facebook的infer检测工具的安装
缘由 由于公司产出代码的时候会使用静态扫描工具检测代码的质量,所以自己就想动手尝试一番infer整个的使用方式和使用效果,便动手安装了infer,结果安装过程中遇见太多的坑,导致很多时候都安装失败,这 ...
- Linux运维常用命令详解
1.ls 文件属性: -:普通文件 d:目录文件 b:块设备 c:字符设备文件 l:符号连接文件 p:命令管道 s:套接字文件 文件权限: 9位数字,每3位一组 文件硬链接次数 文 ...