• 单链表的各种操作 笔试 面试


    一、链表与数组的 差别
    1、逻辑结构   数组必须事先定义固定的长度  不能动态的增减   链表是动态分配内存
    2、内存结构   数组从栈中分配空间   链表在堆中
    3、数组在内存中顺序存储   链表随机存储    数组訪问效率高   链表插入删除方便
    4、数组存在越界问题 


    定义表头。 为方便操作 表头数据域为空
    二、单链表插入 删除
    bool insertList(List head, Type x, int index){


    Node *p;
    p = head;
    int j = 1;
    while(p->next&& j < index){
    p = p->next;
    ++j;
    }
    if(p==NULL) return ERROR;
    Node *tmp = (Node *)malloc(sizeof(Node));
    tmp->data = x;
    tmp->next = p->next; //tmp的后继指向原index位置的结点
    p-next = tmp; //p的后继为新结点
    return OK;
    }
    bool deleteList(List head, int index){
    Node *p = head;
    int j = 1;
    while(p->next!=NULL&&j < i){
    p = p->next;
    ++j;
    }// p->next为第index个
    if(p==NULL || p->next==NULL || j > i) return ERROR; //i可能为负值
    Node *tmp = p->next; //tmp指向第index个
    p->next = tmp->next; //第index+1个取代index
    free(tmp);//释放空间
    return OK;
    }


    三、找出单链表中的倒数第k个元素
    解题思路
    1、先遍历一遍 计算长度。 再找出后k个
    2、双路齐下  p1从第一位開始。p2从第k为開始遍历  直到p2走到头
    思路2代码:
    Node* find(Node* head, int index){
    Node *p1,*p2;
    p1 = head;
    p2 = head;
    for(int i = 0; i < index; i++){ 
    p2 = p2->next; //p2向后移k位
    }
    while(p2!=NULL){
    p1 = p1->next;
    p2 = p2->next;
    }
    return p1;
    }


    四、单链表反转
    解题思路:每次操作结点时  标注其前结点 后结点  对其进行操作
    Node* reverse(Node *head){
    Node *prev = NULL;
    Node *pCur = head;
    Node *rHead = NULL;


    while(pCur!=NULL){
    Node *pNext = head->next;
    if(pNext == NULL)
        rHead = pCur;
    pCur->next = prev; //改变顺序  当前结点指向 自己的前一个结点
    prev = pCur; //当前结点变为前结点 (为了下一个结点准备)
    pCur = pNext; //结点后移
    }
    }


    五、从尾到头输出单链表
    1、递归输出
    2、非递归输出
    非递归操作  : 
    1).能够使用 “四” 的代码进行反转  然后输出
    2).遍历结点入栈 然后输出


    六、寻找单链表的中间结点
    1、遍历求长度length  然后再遍历输出
    2、双路齐下   p1走一步 p2走两步 p2走到终点时 p1正好到中点
    Node* findMiddle(Node *head){
    Node *p1 = head;
    Node *p2 = head;
    while(p2->next->next!=NULL){
    p2 = p2->next->next;
    p1 = p1->next;
    }
    return p1;
    }
    七、单链表排序
    与数组排序差别不大,交换元素时 仅仅交换数据域的内容就好。链表的顺序结构不用变化


    八、单链表中随意 交换两个元素 (要注意表头)
    将2个结点进行交换 要注意 next指针的 交换问题
    //将p q结点交换
    Node* swap(Node* head,Node* p,Node* q){
    if(head==NULL || p==NULL ||  q==NULL){
    Print(ERROR);
    return head;
    }
    if(p==q){
    Print(OK);
    return head;
    }
    else if(p->next == q){ //两节点相邻
    Node* prev = getPrev(p);
    p->next = q->next;
    q->next = p;
    prev->next = q;
    }
    else if(q->next == p){
    Node* prev = getPrev(q);
    q->next = p->next;
    p->next = q;
    prev->next = p;
    }
    else if(p!=q){ //两节点不相邻 且不同  交换前后指针域
    Node* prev1 = getPrev(p);
    Node* prev2 = getPrev(q);
    Node* next1 = p->next;
    Node* next2 = q->next;
    p->next = next2;
    prev2->next = p;
    q->next = next1;
    prev1->next = q;
    }
    return head;
    }




    九、检測一个较大的单链表是否有环
    双路齐下法  一个走一步一个走2步 看是否会相遇


    十、推断两个(无环)单链表是否交叉
    推断最后一个结点是否同样


    十一、删除单链表中的反复结点
    哈希, 建议一hash_map ,遍历链表 若结点出现反复则删除


    十二、合并两个有序链表(非交叉)
    1、递归
    Node* Merge(Node* head1, Node* head2){
    if(head1==NULL)
    return head2;
    if(head2==NULL)
    return head1;
    Node* head=NULL;
    if(head1->data < head2->data){
    head = head1;
    head->next = Merge(head1, head2);
    }else {
    head = head2;
    head->next = Merge(head1, head2);
    }
    return head;
    }
    2、非递归
    Node* Merge(Node*head , Node* head1, Node* head2){
    Node* tmp = head;
    while(head1!=NULL&&head2!=NULL){
    if(head1->data < head2->data){ 
    tmp->next = head1;//指向head1当前结点
    tmp = head1;//移动tmp的位置
    head1 = head1->next;//head1后移
    }else {
    tmp->next = head2;
    tmp = head2;
    head2= head2->next;
    }
    }
    if(head1==NULL)
    tmp->next = head2;
    if(head2==NULL)
    tmp->next = head1;
    return head;
    }
  • 相关阅读:
    类的嵌套
    一种设计模式--单例模式
    python中的类(二)
    Python中的类(一)
    基于session和cookie的登录验证(CBV模式)
    Django中的CBV和FBV
    python3 装饰器
    cookie和session
    基于cookie和session的登录验证
    python3 安装win32api
  • 原文地址:https://www.cnblogs.com/tlnshuju/p/7061220.html
Copyright © 2020-2023  润新知