单循环链表一次找到倒数第n个数的值

本文介绍了如何在单循环链表中仅遍历一次就找到倒数第n个元素的方法,包括使用两个指针和利用栈的结构特性。特别地,文章提到了方法1中需要注意的输入检测问题,如链表起始指针为空、节点数小于k、k值为0等情况。

要求:仅遍历链表一次
方法1:利用两个指针
方法2:利用栈的结构特性

方法1:
//输入检测一
//1.没有判断开始的指针为空导致访问空指针访问的内存
//2.开始的链表的的节点个数小于输入的k
//3.输入的k值为0,假如k为无符号的整数,则k-1为0xFFFFFFFF

//输入检测一
//1.没有判断开始的指针为空导致访问空指针访问的内存
//2.开始的链表的的节点个数小于输入的k
//3.输入的k值为0,假如k为无符号的整数,则k-10xFFFFFFFF

#include <stdio.h>
#include <time.h>
#include "stdlib.h"
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALUSE 0

typedef int ELemType;
typedef int Status;

typedef struct Node {
    ELemType data;
    struct Node * next;
}Node;

typedef struct Node * LinkList;

int CreateNode(LinkList * L , int n){
    * L = (LinkList)malloc(sizeof(Node));
    if(!(*L))
        return ERROR;
    (*L)->next = NULL;
    int i;
    srand(time(0));
    LinkList p;
    for(i = 0;i<n;i++){
        p = (LinkList) malloc(sizeof(Node));
        p -> data = random()%100 + 1;
        p -> next = (*L)->next;
        (*L)-> next = p;
    }
    return OK;
}


ELemType FindKthFromRail(LinkList  L , int k){

    if (L == NULL || k == 0) {
        return ERROR;
    }

    LinkList firstLink =  L->next;
    LinkList secondLink = NULL;

    for (unsigned int i =0 ; i<k-1; ++i) {
        firstLink = firstLink -> next;
        if (firstLink == NULL) {
            return ERROR;
        }
    }

    secondLink = L->next;

    while (firstLink ->next != NULL) {
        firstLink = firstLink ->next;
        secondLink = secondLink ->next;
    }
    return secondLink->data;
}

void TravseNode(LinkList p ){
    LinkList r = p -> next;
    while (r != NULL) {
        printf("%d \n",r->data);
        r = r->next;
    }
}

int ClearList(LinkList *L){
    LinkList p,q;
    p=(*L)->next;
    while(p){
        q=p->next;
        free(p);
        p=q;
    }

    (*L)->next = NULL;  //头节点的指针域为空
    return OK;
}

#include <stdio.h>
#include <time.h>
#include "stdlib.h"
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALUSE 0
#define MAXSIZE 1000

typedef  int Status;
typedef int  SElemType;
//使用顺序栈
typedef struct {
    SElemType data[MAXSIZE] ;
    int top;
}SqStack;

Status InitStack(SqStack * S){
    S->top = -1;
    return  OK;
}

Status Push(SqStack *s , SElemType e){
    if (s->top == MAXSIZE -1) {
        return ERROR;
    }

    s->top++;
    s->data[s->top] = e;

    return OK;

}

Status Pop(SqStack *s , SElemType * t){
    if (s->top == -1) {
        return ERROR;
    }

    *t = s->data[s->top];
    s->top--;

    return OK;
}

void PrintStack(SqStack s){
    for (int i=s.top; i> -1; i--) {
        printf("%d \n" , s.data[i]);
    }
}

int FindKthFromRail(SqStack *s,unsigned n){
    if(s == NULL || (*s).top < n-1 || n==0)
        return ERROR;
    for (int i=0; i < n-1; i++) {
        (*s).top--;
    }
    return (*s).data[(*s).top];
}

int main(){
    SqStack s;
    InitStack(&s);
    //生成n个随机数
    srand(time(0));
    for (int i=0; i<10; i++) {
       Push(&s , rand()%100+1);
    }
    PrintStack(s);
    int value = FindKthFromRail(&s,2);
    printf("倒数第3个数是%d\n",value);
    return  0;
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值