• 数据结构与算法基础(一)链表(上)


    链表由一系列不必在内存中相连的节点组成,分为单链,双链和循环链表。

    根据链表的存储特点可以得出链表的特点:可以快捷的进行插入和删除操作,但是查找操作费时。

    主要复习下单链表。已c实现单链表的insert,delete等操作。

    链表C语言实现:

    //单链
    struct listNode
    {
     int data;
     listNode* next;
    };
    //在链表position位置前插入节点。
    int insert(listNode *root,int value,int position)
    {
     listNode *p,*s;
     p = root;
     int j = 1;
     while(p&&j<position)
     {
      p = p->next;
      ++j;
     }
     if(p==NULL|| j>position)
     {
      return -1;
     }
     //s = (listNode*)new(listNode);
     s = (listNode*)malloc(sizeof(*root));
     if(s==NULL)
     {
      return -1;
     }
     s->data = value;
     s->next = p->next;
     p->next = s;
     return 1;
    }
    //删除position位置的元素,并由value返回其值
    int deleteNode(listNode *root,int position,int &value)
    {
     int j = 1;
     listNode *p,*q;
     p=root;
     while(p&&j<position)
     {
      p = p->next;
      ++j;
     }
     if((p->next)==NULL||j>position)
     {
      return -1;
     }
     q = p->next;
     p->next =q->next;
     value = q->data;
     free(q);
     return 1;
    }

    //删除给定的节点
    void deleteNode(listNode *node)
    {
     assert(node != NULL);
     listNode * nxt = node->next;
     if(nxt != NULL)
     {
      node->data = nxt->data;
      node->next = nxt->next;
      delete nxt;
      return;
     }
     delete node;
    }

    //单链表反转
    listNode* RevlistNode(listNode * root)
    {
     if(root == NULL)
     {
      return NULL;
     }
     if(root->next == NULL)
     {
      return root;
     }
     listNode *cur,*pre,*nxt;
     pre= NULL;
     cur = root;
     while(cur)
     {
      nxt = cur->next;
      cur->next = pre;
      pre = cur;
      cur=nxt;
     }
     return pre;
    }

    1.单链表反转。

    以微软的一道面试题为例,编写一个函数,给定一个链表的头指针,要求只遍历一次,将单链表中的元素顺序反转过来。

    给出反转函数:

    Node* LinkList_reverse(Node* head) 
    { 
        Node *preNode,*curNode,*nextNode; 
      
        if(head==NULL) return NULL;//空链表 
      
        if(head->next == NULL) return head;//仅一个元素 
      
        curNode = head;preNode=NULL;//初始化 
      
        while(curNode) 
        { 
            nextNode = curNode->next;//先记录下一个结点 
            curNode->next = preNode;//改变链表方向(逆置) 
            preNode = curNode;//将当前结点作为下一次循环的前一个结点 
            curNode = nextNode;//向后推移一个结点 
        } 
      
        return preNode;//当遍历完链表后curNode应该为空,此时preNode链表头(head) 
    } 

    2.链表添加节点

    //在给定的节点前插入新节点
    void LinkList_Add(Node* ptr,Node* newNode)
    {
        int temp = 0;
        newNode->next = ptr->next;
        ptr->next = newNode;
        temp = ptr->e;
        ptr->e = newNode->e;
        newNode->e = temp;
    }

    3.无头链表删除给定节点

    同样以一面试题为例

    假设一个没有头指针的单链表,一个指针指向此单链表中间的一个节点(非第一个或最后一个节点),请将该节点删除。

    //删除节点
    void LinkList_Delete(Node* ptr)
    {
        Node* temp = ptr->next;
        if(temp != NULL)
        {
        ptr->e = temp->e;
        ptr->next = temp->next;
        delete temp;//这里delete好像有问题,以后再看下
        }
    }
  • 相关阅读:
    设计模式
    包装类
    php 闭包的理解
    is_null empty isset等的判定
    PHP基础一 $this ,static 和 self的区别
    lumen安装踩过得坑
    composer的使用和安装
    使用submine来写c++
    php 和 thinkphp中的常量一览
    路径问题 ./ / ../ 空 的区别
  • 原文地址:https://www.cnblogs.com/OSLover/p/2765195.html
Copyright © 2020-2023  润新知