IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 经典笔试&面试题(DS&A之链表) -> 正文阅读

[数据结构与算法]经典笔试&面试题(DS&A之链表)

1 逆向链表

逆向链表是将一个单向链表进行转置,使其头变尾,尾变头,各个结点指向它的前个结点;

void ReverseList(node**head)
{
    node*p,*q,*r;
    p=*head;
    q=p->next;
    while(q!=NULL)
    {
        r=q->next;
        q->next=p;
        p=q;
        q=r;
        
    }
    (*head)->next=NULL;
    *head=p;
}

2 链表排序

指针不变,值改变;

void SortList(node*head)
{
    node*p,*q,*s;
    int t;
    p=head;
    while(p)
    {
        s=p;
        q=p->next;
        while(q)
        {
            if(q->value<s->value)
            {
                s=q;
                
            }
            q=q->next;
            
        }
        if(s!=p)
        {
            t=s->value;
            s->value=p->value;
            p->value=t;
		}
        p=p->next;
    }
}

3 链栈

//创建栈,并初始化
int CreateStack(node**stack)
{
    *stack=NULL;
    return 1;
}
//入栈
int Push(node**stack,void*data)
{
    node* elem;
    elem=(node*)malloc(sizeof(node));
    if(!elem)
    {
        return 0;
    }
    elem->data=data;
    elem->next=*stack;
    *stack=elem;
    return 1;
}
//出栈
int Pop(node**stack,void**data)
{
    node*elem;
    if((elem=*stack)==NULL)
    {
        return 0;
	}
    *data=elem->data;
    *stack=elem->next;
    free(elem);
    return 1;
}
//销毁栈
int DeleteStack(node**stack)
{
    node* next;
    while(*stack)
    {
        next=(*stack)->next;
        free(*stack);
        *stack=NULL;
    }
    return 1;
}

5 链队

typedef struct Qnode_
{
    int data;
    struct Qnode_*next;
}Qnode;
Qnode*front;//队头指针
Qnode*rear;//队尾指针

//创建队列
int CreateQue(Qnode**que)
{
    *que=NULL;
    front=rear=NULL;
    return 1;
}
//销毁队列
int DeleteQue(Qnode**que)
{
    Qnode*next;
    while(*que)
    {
        next=(*que)->next;
        free(*que);
        *que=next;
    }
    return 1;
}
//尾插
int EnQueue(int*e)
{
    Qnode*p;
    p=(Qnode*)malloc(sizeof(Qnode));
    if(p==NULL)
    {
        return 0;
    }
    p->data=*e;
    p->next=NULL;
    if(rear==front)
    {
        front=rear=p;
        
    }
    else
    {
        rear->next=p;
        rear=p;
    }
    return 1;
    
}
//队头出队
int DeQueue(int*e)
{
    Qnode*p;
    if(front==rear)
    {
        return 0;
    }
    p=front->next;
    *e=p->data;
    front->next=p->next;
    if(p==rear)
    {
        front=rear;
    }
    free(p);
    return 1;
}

6 链表删除结点

int Delete(node*elem)
{
    node*curPos=head;
    
    //特殊情况1:欲删除的结点为NULL
    if(elem==NULL)
        return 0;
    //特殊情况2:欲删除的结点为head
    if(elem==head)
    {
        head=elem->next;
        free(elem);
        if(head==NULL)
        {
            tail=NULL;
		}
        return 1;
    }
    
    while(curPos)
    {
        if(curPos->next==elem)
        {
            curPos->next=elem->next;
            free(elem);
            //特殊情况3:删除的结点是tail
            if(curPos->next==NULL)
            {
                tail=curPos;
            }
            return 1;
        }
        curPos=curPos->next;
    }
    return 0;
}

7 链表插入新结点

int InsertAfter(node*elem,int data)
{
    node*newElem,*curPos=head;
    newElem=(node*)malloc(sizeof(node));
    if(newElem==NULL)
    {
        return 0;
	}
    newElem->data=data;
    if(elem==NULL)
    {
        newElem->next=head;
        head=newElem;
        if(tail==NULL)
        {
            tail=newElem;
        }
    	return 1;    
    }
    while(curPos)
    {
        if(curPos==elem)
        {
            newElem->next=curPos->next;
            curPos->next=newElem;
            if(newElem->next==NULL)
            {
                tail=newElem;
            }
            return 1;
        }
        curPos=curPos->next;
    }
    free(newElem);
    return 0;
    
}

8 判断单向链表是否存在循环

算法:使用步长法判断链表是否存在循环,设置两个遍历,第一个遍历步长是第二个遍历的步长的两倍,如果这两个遍历相遇,则单向链表有环路;

int FindLoop(node*head)
{
    node*p;
    node*q;
    if(head==NULL)
    {
        return 0;
    }
    p=head;
    q=head->next;
    while(q!=NULL&&q->next!=NULL&&p!=q)
    {
        p=p->next;
        q=q->next->next;
    }
    if(p==q)
    {
        return 1;
    }
    else
    {
        return 0;
    }
}

9 找出倒数第m个元素

1 给定一个单向链表,高效算法找出链表中的倒数第m个元素:

2 规定:当m=0,链表的最后一个元素将被返回;

3 分析:
假设有n个元素,倒数第m个元素即正数的第n-m个元素;

4 思路:
声明两个指针,一个指针首先遍历m个元素,第二个指针与第一个指针同时遍历链表,直到第一个指针遍历结束,第一个指针遍历了剩下的n-m个元素,第二个指针遍历到了第n-m个元素;

node* FindMToLastElement(node*head,int m)
{
    node*current,*mBehind;
    int i;
    //current指针向后移动m个元素
    current=head;
    for(int i=0;i<m;i++)
    {
        if(current->next)
        {
            current=current->next;
        }
        else
        {
            return NULL;
        }
        
    }
    //mBehind从头开始,与current一起向后移动
    mBehind=head;
    while(current->next)
    {
        current=current->next;
        mBehind=mBehind->next;
        
    }
    //此时,current向后移动了n-m个元素,而mBehind和current向后移动了n-m个元素,刚好为倒数第m个元素
    return mBehind;
}
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-09-29 10:33:19  更:2021-09-29 10:34:45 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 5:42:53-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码