1、编程实现单链表删除节点。

      解析:如果删除的是头节点,如下图:

则把head指针指向头节点的下一个节点。同时free p1,如下图所示:

如果删除的是中间节点,如下图所示:

则用p2的next指向p1的next同时,free p1 ,如下图所示:

2、编写程序实现单链表的插入。

      解析:单链表的插入,如下图所示:

如果插入在头结点以前,则p0的next指向p1,头节点指向p0,如下图所示:

如果插入中间节点,如下图所示:

则先让p2的next指向p0,再让p0指向p1,如下图所示:

如果插入尾节点,如下图所示:

则先让p1的next指向p0,再让p0指向空,如下图所示:

3、编写实现单链表的逆置。

解析:单链表模型如下图所示:

进行单链表逆置,首先要让p2的next指向p1,如下图所示:

再由p1指向p2,p2指向p3,如下图所示:

让后重复p2的next指向p1,p1指向p2,p2指向p3。

 #include<iostream>
using namespace std;
typedef struct Student{
int data;
struct student *next;//结构体重如果没有用typedef定义结构体,那么想要声明一个结构体的变量,就需要加上struct }node; node *creat(){
/*① 建立头结点
② 循环输入节点值,0停止输入,其他则继续输入
③ 插入一个值,新建一个节点存储该值,赋值操作,指针修改操作
上一个节点的next指向新建立的节点,临时指针指向当前节点方便递增操作
④ 返回一个头结点,该节点不为空
*/
node *head,*p,*s;//头结点,p临时头节点,s为新建立的节点
int x,cycye=;//输入停止变量
head=(node*)malloc(sizeof(node));//建立头结点
p=head;
while(cycle){
cout<<"请输入链表数据:"<<endl;
cin>>x;
if(x!=){//当输入不为0,继续输入
s=(node*)malloc(sizeof(node));//S为新建立的节点
s->data=x;
cout<<s->data<<endl;
p->next=s;
p=s;//临时指针递增
}
else{
cycle=;//停止输入
}
p->next=NULL;//指针指向链表尾端
cout<<" yyy"<<head->next->data<<endl;
head=head->next;
return (head);
}
}
//打印链表
void print(node *head){
/* ① 该链表为空,不输出。
② 该链表不为空且不止一个节点:头结点没有值,则从头结点的下一个节点开始输出
*/
node *tem_node;//临时节点
tem_node=head;
//这里还要输出链表长度
int length=length(head);
cout<<"该链表长度为:"<<length<<endl; if(head!=NULL){
tem_node=tem_node->next;//因为该头结点没有值,所以要指向下一个
}
while(tem_node!=NULL){
cout<<"节点值:"<<tem_node->data<<endl;
tem_node=tem_node->next;
}
}
//删除节点
node *remove(node *head,int num){
/*① 删除头结点:把头结点的指针指向下一个节点,再把头结点移除
② 删除中间节点:前驱节点的next指向删除节点的next
*/
node *p1,*p2;
p1=head;
//找到删除位置
while(num!=p1->data &&p1->next!=NULL){//删除的值不为头结点值,并且头结点不为空
p2=p1;//删除节点的上一个节点
p1=p1->next;//找到删除节点
}
if(num==p1->data){//如果存在p1节点,删除
if(p1==head){//删除头结点
head=p1->next;
free(p1);
}
else{
p2->next=p1->next;
}
}
else{
cout<<"不存在值为"<<num<<"的节点!"<<endl;
}
return (head);
}
node *insert(node *head,int num){
/*① 从头部插入:头指针指向插入节点,新插入节点next指向原头结点
② 从中间插入:插入位置的前一个节点next指向新插入节点,新插入节点nex指向后一个节点
③ 从尾部插入:和2类似,只是最后是新插入节点next指向NULL
*/
node *p1,*p2,*p3;
p2=head;
p1=(node*)malloc(sizeof(node));//新增节点
p1->data=num;
while(p1->data > p2->data && p2->next!=NULL){//找插入点
p3=p2;
p2=p2->next;
//p2是后一个,P3是前一个
}
//判断这个插入的位置
if(p1->data<=p2->data){
if(head==p2){//从头结点插入
p1->next=p2;
head=p1;
}
else {//从中间节点插入
p3->next=p1;
p1->next=p2;
}
}
else{//没有比他大的数,从尾部插入
p2->next=p1;
p1->next=NULL;
}
return (head);
}
//链表排序
node *sort(node *head){
/*冒泡排序法解决*/
node *p,*p2,*p3;
int n;
int temp;
n=length(head);
if(head==NULL ||head->next==NULL)//如果只有一个或者没有节点
return head;
p=head;
for(int j=;j<n;++j) {
p=head;
for(int i=;i<n-j;++i) {
if(p->data > p->next->data){
temp=p->data;
p->data=p->next->data;
p->next->data=temp;
}
p=p->next;
}
}
return (head); }
//链表的转置
node *reverse(node *head){
/**/
node *p1,*p2,*p3;
if(head==NULL || head->next==NULL){
return head;
}
p1=head;
p2=p1->next;
while(p2){
p3=p2->next;
p2->next=p1;
p1=p2;
p2=p3;
}
head->nex=NULL;
head=p1;
return head;
}
//链表测长
int length(node *head){
node *tem_node;
tem_node=head;
int n=;
while(tem_node!=NULL){
n++;
tem_node=tem_node->next;
}
return n;
} int main(){ }

4、编程实现删除单链表的头元素。

答案:

    

 #include<iostream>
using namespace std; void Removehead(node *head){
node * p=head;
head=head->next;
free(p);
}

5、给出一个单链表,不知道节点N的值,怎么只遍历一次就可以求出中间节点,写出算法。

解析:设立两个指针,比如*p和*q。p每次移动两个位置,即p=p->next->next,q每次移动一个位置,即q=q->next。当p达到最后一个节点时,q就是中间节点了。

  答案:

    

 #include<iostream>
using namespace std;
//给出一个单链表,不知道节点N的值,怎么遍历一次就可以求出中间节点
void searchMid(node *head,node *mid){
node *p,*q;
p=head;
q=head;
while(p->next->next!=NULL){
p=p->next->next;//p移动两个位置
q=q->next;//q移动一个位置,这样相当于p走了两倍,q走了一倍就到达了中点
mid=q;
}
}

6、给定一个单向链表,设计一个时间优化并且空间优化的算法,找出该链表的倒数第m个元素。实现您的算法,注意处理相关的出错情况。m定义为当m=0时,返回链表最后一个元素。

解析:这是一个难题,我们需要的是倒数第m个元素,所以如果我们从某个元素开始,遍历了m个元素之后刚好到达链表末尾,那么这个元素就是要找的元素。也许从链表的尾部倒推回去不是最好的办法,那么我们可以从链表头开始计数。

思路一:我们可以先一次遍历求出链表的总长度n,然后顺序变量求出第n-m个元素,那么这个就是我们要找的元素了。

思路二:我们用两个指针,一个当前位置指针p和一个指向第m个元素的指针q,需要确保两个指针之间相差m个元素,然后以同样的速度移动它们,如果当q到达链表末尾时,那么p指针就是指向倒数第m个元素了。

答案:

    

 #include<iostream>
using namespace std;
//思路二
node* search_last_m_num(node *head,int m){
if(head==NULL)
return NULL;
node *p1,*p2;
p1=head;
p2=head;
while(m){//这样p1和p2相差M个单位长度,当p2走到尽头的时候,p1指向的元素就是倒数第m个元素
if(p2->next!=NULL){
p2=p2->next;
m--;
}
else
return NULL;
}
while(p2->next!=NULL){
p1=p1->next;
p2=p2->next;
}
return p1;
}

C++面试笔记--单链表的更多相关文章

  1. c++学习笔记—单链表基本操作的实现

    用c++语言实现的单链表基本操作,包括单链表的创建(包括头插法和尾插法建表).结点的查找.删除.排序.打印输出.逆置.链表销毁等基本操作. IDE:vs2013 具体实现代码如下: #include  ...

  2. python经典面试算法题1.3:如何计算两个单链表所代表的数之和

    本题目摘自<Python程序员面试算法宝典>,我会每天做一道这本书上的题目,并分享出来,统一放在我博客内,收集在一个分类中. 1.2 如何实现链表的逆序 [华为笔试题] 难度系数:⭐⭐⭐ ...

  3. LeetCode 笔记系列六 Reverse Nodes in k-Group [学习如何逆转一个单链表]

    题目:Given a linked list, reverse the nodes of a linked list k at a time and return its modified list. ...

  4. 面试之路(10)-BAT面试之java实现单链表的插入和删除

    链表的结构: 链表在空间是不连续的,包括: 数据域(用于存储数据) 指针域(用于存储下一个node的指针) 单项链表的代码实现: 节点类 构造函数 数据域的get,set方法 指针域的get,set方 ...

  5. 数据结构(java版)学习笔记(三)——线性表之单链表

    单链表的优点: 长度不固定,可以任意增删. 单链表的缺点: 存储密度小,因为每个数据元素,都需要额外存储一个指向下一元素的指针(双链表则需要两个指针). 要访问特定元素,只能从链表头开始,遍历到该元素 ...

  6. 《程序员代码面试指南》第二章 链表问题 将单链表每K个节点之间逆序

    样例 链表1-2-3-4-5-6-7-8-9-10 K=3 ,结果 3-2-1-6-5-4-9-8-7-10 java代码 /** * @Description:将单链表每K个节点之间逆序 * @Au ...

  7. 《程序员代码面试指南》第二章 链表问题 在单链表和双链表中删除倒数第K个节点

    题目 在单链表和双链表中删除倒数第K个节点 java代码 /** * @Description:在单链表和双链表中删除倒数第K个节点 * @Author: lizhouwei * @CreateDat ...

  8. 左神算法书籍《程序员代码面试指南》——2_11将单链表的每K个节点之间逆序

    [题目]给定一个单链表的头节点head,实现一个调整单链表的函数,使得每K个节点之间逆序,如果最后不够K个节点一组,则不调整最后几个节点.例如:链表:1->2->3->4->5 ...

  9. 左神算法书籍《程序员代码面试指南》——2_02在单链表和双链表中删除倒数第k个字节

    [题目]分别实现两个函数,一个可以删除单链表中倒数第K个节点,另一个可以删除双链表中倒数第K个节点.[要求]如果链表长度为N,时间复杂度达到O(N),额外空间复杂度达到O(1).[题解]从头遍历链表, ...

随机推荐

  1. Apache POI实现excel导出

    链接:http://poi.apache.org/ Excel数据导出步骤: 使用poi 完成账户数据的导出功能 导入poi  jar包并添加到classpath中 1.查询数据 2.定义导出头 St ...

  2. Python 中的几种矩阵乘法 np.dot, np.multiply, *

    使用array时,运算符 * 用于计算数量积(点乘),函数 dot() 用于计算矢量积(叉乘).使用matrix时,运算符 * 用于计算矢量积,函数 multiply() 用于计算数量积. 下面是使用 ...

  3. Angular 隨記

    Windows下更新Node 和NPM方法 管理員模式打開powershell 執行以下命令: Set-ExecutionPolicy Unrestricted -Scope CurrentUser ...

  4. 使用.NET中的XML注释(一) -- XML注释标签讲解

    一.摘要 .Net允许开发人员在源代码中插入XML注释,这在多人协作开发的时候显得特别有用. C#解析器可以把代码文件中的这些XML标记提取出来,并作进一步的处理为外部文档. 这篇文章将展示如何使用这 ...

  5. RequireJS 也可以引入 VUE

    RequireJS 也可以引入 VUE 由于 FastAdmin 是使用 RequireJS 导入 JS 模块的. 有人想把 VUE 也引入进去,虽然说也是可以,VUE 还是推荐使用 Webpack ...

  6. 如何打开 Windows 的热键提示

    如何打开 Windows 的热键提示 很早之前我记的 Windows 是有热键提示的,不知道什么时候开始默认不显示了,难道 微软是为是美观? 找了一下原来是有地方可以设置的.

  7. Day2-Python基础2---列表、元组操作

    一.列表 列表是我们最以后最常用的数据类型之一,通过列表可以对数据实现最方便的存储.修改等操作 定义列表 names = ["maqing"," peilin" ...

  8. HTTP-Runoob:HTTP请求方法

    ylbtech-HTTP-Runoob:HTTP请求方法 1.返回顶部 1. HTTP请求方法 根据HTTP标准,HTTP请求可以使用多种请求方法. HTTP1.0定义了三种请求方法: GET, PO ...

  9. md5加密(1)

    package com.js.ai.modules.pointwall.util; import java.security.MessageDigest; import java.security.N ...

  10. MyBatis----延迟加载demo

    一:创建数据库脚本drop table project_info; drop table status; create table status( id number(10) primary key, ...