链表是一种动态数据结构。每次添加一个节点时分配一次内存。由于没有闲置的内存,链表的空间效率比数组要高。
常用的链表有:单向链表,双向链表,循环链表
下面是一个单项链表添加节点和删除节点的代码
/*一个单向链表的节点定义如下*/
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个数
判断链表是否有环