c语言找出链表中倒数第k的数,查找链表中倒数第k个结点
题目:输入一个单向链表,输出该链表中倒数第 k 个结点。链表的倒数第 0 个结点为链表的尾指针。
分析:为了得到倒数第 k 个结点,很自然的想法是先走到链表的尾端,再从尾端回溯 k 步。可是输入的是单向链表,只有从前往后的指针而没有从后往前的指针。因此我们需要打开我们的思路。 既然不能从尾结点开始遍历这个链表,我们还是把思路回到头结点上来。假设整个链表有 n 个结点,那么倒数第 k 个结点是从头结点开始的第 n-k-1 个结点(从 0 开始计数)。如果我们能够得到链表中结点的个数 n ,那我们只要从头结点开始往后走 n-k-1 步就可以了。如何得到结点数 n ?这个不难,只需要从头开始遍历链表,每经过一个结点,计数器加一就行了。 这种思路的时间复杂度是 O(n) ,但需要遍历链表两次。第一次得到链表中结点个数 n ,第二次得到从头结点开始的第 n-k-1 个结点即倒数第 k 个结点。 如 果链表的结点数不多,这是一种很好的方法。但如果输入的链表的结点个数很多,有可能不能一次性把整个链表都从硬盘读入物理内存,那么遍历两遍意味着一个结 点需要两次从硬盘读入到物理内存。我们知道把数据从硬盘读入到内存是非常耗时间的操作。我们能不能把链表遍历的次数减少到 1 ?如果可以,将能有效地提高代码执行的时间效率。 如果我们在遍历时维持两个指针,第一个指针从链表的头指针开始遍历,在第 k-1 步之前,第二个指针保持不动;在第 k-1 步开始,第二个指针也开始从链表的头指针开始遍历。由于两个指针的距离保持在 k-1 ,当第一个(走在前面的)指针到达链表的尾结点时,第二个指针(走在后面的)指针正好是倒数第 k 个结点。 这种思路只需要遍历链表一次。对于很长的链表,只需要把每个结点从硬盘导入到内存一次。因此这一方法的时间效率前面的方法要高。
#include #include typedef struct list{ int num; struct list *next; }LIST; LIST *create_list(int n){ LIST *head=NULL; LIST *tmp=NULL; LIST *last=NULL; int i; for(i=1;i<=n;i++){ tmp=(LIST *)malloc(sizeof(LIST)); tmp->num=i; if(1==i) head=tmp; else last->next=tmp; tmp->next=NULL; last=tmp; } return head; } void print_list(LIST *head){ if(NULL==head){ printf("list is null./n"); return; } LIST *p=head; while(p!=NULL){ printf("list num is %d/n",p->num); p=p->next; } } LIST *find_last_k_node(LIST *head,int k){ if(NULL==head) { printf("list is null./n"); return NULL; } LIST *p=head->next; LIST *q=head->next; int i; for(i=0;inext; } while(q!=NULL){ q=q->next; p=p->next; } return p; } int release_list(LIST *head){ if(NULL==head) { printf("head is null./n"); return 0; } LIST *tmp=head; LIST *l=head; while(l!=NULL){ tmp=l; l=l->next; free(tmp); } head=NULL; return 0; } int main(){ LIST *head=NULL; LIST *pos=NULL; int n=5; int k=3; head=create_list(n); print_list(head); printf("******************************/n"); pos=find_last_k_node(head,k); print_list(pos); release_list(head); return 0; }
运行结果:
[root@localhost list]# ./a.out
list num is 1
list num is 2
list num is 3
list num is 4
list num is 5
******************************
list num is 3
list num is 4
list num is 5
c语言找出链表中倒数第k的数,查找链表中倒数第k个结点相关推荐
- C语言找出数组中最小的数和它的下标
C语言找出数组中最小的数和它的下标,然后把它和数组中最前面的元素对换位置 #include <stdio.h> int main() {int A[10]={3,7,5,9,10,2,1, ...
- c语言找出一个数组中出现次数最多的那个元素,c语言找出数组中出现次数最多地那个元素...
matlab中如何找出不同维度矩阵出现次数最多的数组并记录其个数 首先是胞矩阵中的序列问题,不妨假设AA{1}是一个多行两列的数据,AA{2}同例.程序如下clcclearallAA{1}=[12;2 ...
- C语言找出两个字符串唯一不同的一个字符(附完整源码)
C语言找出两个字符串唯一不同的一个字符 C语言找出两个字符串唯一不同的一个字符完整源码(定义,实现,main函数测试) C语言找出两个字符串唯一不同的一个字符完整源码(定义,实现,main函数测试) ...
- C语言——找出矩阵最大值
C语言--找出矩阵最大值 问题描述: 代码: # include <stdio.h>int main() {int a[3][4];int i, j;int maxi = 0;int ma ...
- 找出1到n的守形数c语言,c语言循环语句训练题(6页)-原创力文档
. 练习题: 1. 找出 1~n之间的守形数 : 从个位数看起 ,n 的所有位与 n*n 的对应位完全相同 . 2. 任给两个整数 , 判断一个是否包含在另一个中 . 例如 :567 在 12567中 ...
- c语言实现在数组中找一个数字显示,C语言找出数组中的特定元素的算法解析
问题描述:一个int数组,里面数据无任何限制,要求求出所有这样的数a[i],其左边的数都小于等于它,右边的数都大于等于它.能否只用一个额外数组和少量其它空间实现. 思路:如果能用两个辅助数组,那么相对 ...
- 用vb脚本语言找出c盘所有文件及其子文件中后缀名为.txt的文档,2012年3月计算机二级VB练习题及答案:文件...
一. 单选题 1.关于顺序文件的描述,下面正确的是 ________. A) 每条记录的长度必须相同 B) 可通过编程对文件中的某条记录方便地修改 C) 数据只能以ASCII码形式存放在文件中,所以可 ...
- c语言:找出4数中最大值最小值
n1.n2.n3.n4是一组需要找出最大最小值的整数 #include <stdio.h>int main() {int n1, n2, n3, n4, max1, max2, min1, ...
- C语言找出4个最大和4个最小数,济南大学C语言程序设计教案:C语言实验课程第四课.doc...
济南大学C语言程序设计教案:C语言实验课程第四课 C语言实验课程第四课 实验一 数组与函数.数组与指针 一.实验目的 1 掌握数组名作为函数参数的含义.使用方法. 2 掌握多维数组作为函数参数的使用方 ...
最新文章
- 信息收集渠道:文本分享类网站Paste Site
- 二、Windows基础数据类型
- Cuda中Global memory中coalescing例程解释
- 让同步函数同步执行,异步函数异步执行,并且让它们具有统一的 API
- mdin偏移_C8051F020入门指导重点.ppt
- 【排序】LeetCode 75. Sort Colors
- SQL Server 2016 bak文件还原
- shell脚本加密工具—shc
- JAVA实现商品信息管理系统
- 计算机软件考试难,计算机技术与软件专业技术资格考试难吗
- 深度优先遍历和广度优先遍历
- 模拟双色球系统判断中奖情况
- CSS3实现流星动画
- 微信个人号客服系统淘宝客发单机器人sdk服务端接口列表
- 案例3 淘宝点击关闭二维码
- 终于搞清楚了ADO数据库连接中的Persist Security Info参数的作用
- pe系统如何读取手机_如何让Android手机在winpe连接电脑后显示?
- Latex中自动引用参考文献的方法,一分钟搞定
- Python入门学习笔记
- L1-044 稳赢 (15 分)