数据结构——链表(1)如何找出链表中的倒数第k个元素

方法一:①遍历链表,得到链表的长度n的值;②将倒数的k的序号转换到顺序排号(n-k+1);③遍历链表,直到找到第(n-k+1)个元素。两次遍历,时间复杂度为O(n)。
方法二:从第一个元素开始,遍历k个元素,判断呢是否为NULL,若为空,则找到第k个元素。多次遍历,时间复杂度为O(kn)。
方法三:设置两个指针,第二个比第一个先往后移动k步(因为包含头结点)。则这两个指针之间的距离刚好为k。那么,当第二个指针指向NULL的时候,第一个指针就刚好指在倒数第k个位置。只需一次遍历。

#include <stdlib.h>
#include<iostream>


typedef int ElemType;
struct Node
{
    ElemType data;
    struct Node *next;
};

typedef struct Node Node;
typedef struct Node* Linklist;


#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0

#define MaxSize 30  //存储空间初始分配量
typedef int Status;


Status InitList1(Linklist *L)
{
    *L= (Linklist)malloc(sizeof(Node)); //产生头结点,并且使得L指向该头结点
    if (!(*L))  
        return ERROR;                           //令头结点的指针域为空
    (*L)->next = NULL;
    return OK;

}

//获取链表的长度
int ListLength1(Linklist L)
{
    Linklist p;
    p=L->next;
    int len=0;
    while(p)
    { 
        p=p->next;
        len++;
    }
    return len;
}

//找出单链表中的倒数第k个元素
int findInLinkList1(Linklist L, int k)
{
    Linklist p;
    p=(L);
    p=L->next;
    int len=ListLength1(L);
    int j=1;
    while(p && j<(len-k+1) )
    {
        p=p->next;
        j++;
    }
    int num=p->data;
    return num;

}

int findInLinkList2(Linklist L,int k)
{
    Linklist p,q;
    p=L;
    q=p;
    while(p!=NULL)
    {
        p=q->next;

    for(int i=1;i<k;i++)
    {
        p=p->next;

    }

    }

    int num =p->data;
    return num;

}

int findInLinkList3(Linklist L, int k)
{
    Linklist p,q;
    p=L;
    q=p;
    int m=0;
    for(int i=1;i<=k;i++)
    {
        q=q->next;
        m++;
    }
    int j=0;
    while(q!=NULL)  
    {
        p=p->next;
        q=q->next;
        j++;
    }
    int num;
    num=p->data;
    return num;


}

//对链表进行头插法
Status ListInsert1(Linklist *L,int i, ElemType e)
{
    Linklist p,s;
    p=(*L);
    int j=1;
    while(p && j<i)
    {
        p=p->next;
        j++;
    }
    if (!p || j>i)
        return ERROR;

    s=(Linklist)malloc(sizeof(Node));
    s->data=e;
    s->next =p->next;
    p->next =s;
    return OK;



}



int main()
{
    Linklist L;
    InitList1(&L);          //首先,要初始化一个链表

    int len1=ListLength1(L);
    printf("%d\n",len1);

    for (int i=1;i<=5;i++)
    {
        ListInsert1(&L,1,i);
    }
    int len2=ListLength1(L);
    printf("%d\n",len2);

    Linklist p =L;
    for(int i=1;i<=len2;i++)
    {
        printf("%d\n",p->next->data);
        p=p->next;
    }

    int num1=findInLinkList1(L,2);//方法一
    printf("num1=%d\n",num1);

    int num2=findInLinkList3(L,2);//方法二
    printf("num2=%d\n",num2);

    int num3=findInLinkList3(L,2);//方法三
    printf("num3=%d\n",num3);


    getchar();

}

猜你喜欢

转载自blog.csdn.net/zhangying_496/article/details/81224931