链表总结

链表是一种动态数据结构。每次添加一个节点时分配一次内存。由于没有闲置的内存,链表的空间效率比数组要高。
常用的链表有:单向链表,双向链表,循环链表
下面是一个单项链表添加节点和删除节点的代码

/*一个单向链表的节点定义如下*/
struct ListNode
{
    int nValue;//数据域
    ListNode* pNext;//指针域
};
/*向链表末尾添加一个节点的C++代码如下*/
void AddToTail(ListNode** pHead, int value){//第一个参数pHead是一个指向指针的指针,即*pHead指向头结点
    ListNode* pNew = new ListNode();//定义一个新的节点。这句话可以理解为,动态分配一个ListNode型的节点,并使pNew指向该节点。
    pNew->nValue = value;
    pNew->pNext = nullptr;
    if(*pHead == nullptr)//如果是空链表,直接将头指针指向新建立的节点
        *pHead = pNew;
    else{
        ListNode* pNode = *pHead; 
        while(pNode->pNext != nullptr)
            pNode = pNode->pNext;
        pNode->pNext = pNew;
    }
}
/*在链表中找到第一个含有某值的节点并删除该节点*/
void RemoveNode(ListNode** pHead, int value){
    if(pHead == nullptr || *pHead == nullptr)//首先判断链表是否为空
        return;
    ListNode* pToBeDeleted = nullptr; //定义一个pToBeDeleted指针,用来指向待删除的节点
    if((*pHead)->value == value){//如果头结点即是待删除节点,则要将头指针指向下一个节点
        pToBeDeleted = *pHead;
        *pHead = (*pHead)->pNext;
    }
    else{
        ListNode* pNode = *pHead;
        while(pNode->pNext != nullptr && 
              pNode->pNext->nValue != value)
            pNode = pNode->pNext;
        if(pNode->pNext != nullptr && pNode->pNext->nValue == value){
            pToBeDeleted = pNode->pNext;
            pNode->pNext = pToBeDeleted->pNext;
        }
    }
    if(pToBeDeleted != nullptr){//此时pToBeDeleted指向了待删除的节点,用delete来释放节点
        delete pToBeDeleted;
        pToBeDeleted->pNext = nullptr;
    }
}

补一下new和delete的知识。
new和delete运算符分别用于动态分配内存和动态回收。用new动态分配的内存中存放随机值,在使用前应初始化。
在程序执行过程中,如果希望根据输入或计算的一个值来说明一个数组的大小,用传统的数组说明语句是无法实现的,例如:

int n;
cin>>n;
float a[n];

编译器指出数组a说明无效,因为n不是常量
但用new运算符来申请分配内存空间是可以的,例如:

int n;
cin>>n;
float *p = new folat[n];//申请n个动态空间
p[0] = 1.1;
...
delete []p;//回收动态空间

相关面试题

单向链表反转

LinkList* reverse(LinkList* head){
    LinkList* p, q, pr;
    p=head->next;
    pr=p->next;
    q = NULL;
    while(p!= NULL){
        p->next = q;
        q=p;
        p = pr;
        pr = p->next;
    }
    head -> next = q;
    return head;
}

判断链表中环的入口点

/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) :
        val(x), next(NULL) {
    }
};
*/
class Solution {
public:
    ListNode* EntryNodeOfLoop(ListNode* pHead)
    {
        if(pHead == NULL || pHead->next == NULL){
            return null;
        }
        ListNode* fast = pHead;
        ListNode* slow = pHead;
        while(fast != slow && fast->next != NULL && fast != NULL){
            slow = slow->next;
            fast = fast->next->next;
        }
        if(fast == slow){
            fast = pHead;
            while(fast != slow){
                fast = fast->next;
                slow = slow->next;
            }
            if(fast == slow){
                return fast;
            }
        }
        else{
            return null;
        }
    }
};

查找链表的倒数第k个数
判断链表是否有环

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值