DS 单链表的实现

本文介绍了一个使用C++实现的带头节点单链表的数据结构。该链表提供了创建、显示、销毁等基本操作,并实现了插入、删除、查找等功能。通过具体实例展示了链表的各种操作方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

// 带头节点单链表的C++实现  
  
#include "stdafx.h"  
#include <iostream>  
#include <iomanip>  
using namespace std;  
  
class CNode                          //节点  
{  
public:  
    int data;  
    CNode *next;  
    CNode()  
    {  
        next=NULL;  
    }     
};  
  
class CList  
{  
private:  
    CNode *head;                                                    //头节点  
public:  
    CList();  
    void Create();                                                     //创建链表  
    void Display()const;                                           //显示链表  
    ~CList();                                                            //销毁链表  
    int getlen() const;                                              //获取链表长度  
    bool isEmpty() const;                                         //判断链表是否为空  
    bool Find(const int e) const;                              //在链表中查找某个值  
    CNode* GetNode(int i) const;                            //返回第i个节点  
    void Insert(int i,const int e);                               //在第i个位置插入元素e  
    void Delete(const int e);                                     //删除一个元素e   
    void Reverse();                                                   //链表逆置      
};  
  
CList::CList()  
{  
    head=new CNode();  
    head->next=NULL;   
}  
  
void CList::Create()  
{  
    CNode *p,*q;  
    p=head;  
    q=new CNode();  
    cout<<"请输入值(按ctrl+z停止): "<<endl;  
    while(cin>>q->data)  
    {  
        p->next=q;         
        p=q;  
        q=new CNode();  
    }  
}  
  
void CList::Display() const             //显示链表  
{  
    CNode *p;  
    p=head->next;  
    while(p)  
    {  
        cout<<p->data<<" ";  
        p=p->next;  
    }  
    cout<<endl;  
}  
  
CList::~CList()  
{  
    CNode *p;  
    while(head)  
    {  
        p=head->next;  
        delete head;  
        head=p;  
    }  
}  
  
int CList::getlen() const  
{  
    int length=0;  
    CNode *p=head->next;  
    while(p)  
    {  
        length++;  
        p=p->next;  
    }  
    return length;  
}  
  
bool CList::isEmpty() const  
{  
    return (head->next==NULL);  
}  
  
bool CList::Find(const int e) const  
{  
    CNode* p=head->next;  
    while(p)  
    {  
        if(p->data==e)  
            return true;  
        p=p->next;  
    }  
    return false;  
}  
  
CNode* CList::GetNode(int i) const  
{  
    if(i<0||i>getlen())                         //i不在链表范围内时,抛出异常  
    {         
        throw i;  
    }  
    CNode* p=head;  
    while(p&&i)  
    {  
        p=p->next;  
        i--;  
    }  
    return p;  
}  
  
void CList::Insert(int i,const int e)  
{  
    CNode *p;  
    CNode *node=new CNode();  
    node->data=e;  
    if(i==1)                                       //在第一个位置插入节点  
    {  
        node->next=head->next;  
        head->next=node;  
    }  
    else   
    {  
        p=GetNode(i-1);  
        if(i==getlen())                         //在链表末位插入节点  
            p->next=node;  
        else  
        {  
            node->next=p->next;  
            p->next=node;  
        }  
    }     
}  
  
void CList::Delete(const int e)  
{  
    if(!Find(e))  
    {  
        cout<<"链表不包含值为"<<e<<"的节点!"<<endl;  
        return;  
    }  
    CNode *p=head;  
    CNode *q=head->next;  
    while(q)  
    {  
        if(q->data==e)  
        {  
            break;  
        }  
        p=p->next;  
        q=q->next;  
    }  
    p->next=q->next;  
    return;  
}  
  
void CList::Reverse()  
{  
    if(isEmpty())  
    {  
        cout<<"链表为空"<<endl;  
        return;  
    }  
    CNode *p,*q;  
    int len=getlen();  
    int i=1;  
    int j=len;  
    while(i<j)  
    {  
        p=GetNode(i);  
        q=GetNode(j);  
        int temp=p->data;  
        p->data=q->data;  
        q->data=temp;  
        ++i;  
        --j;  
    }  
}  
  
int main()  
{  
    CList* link=new CList();  
    link->Create();  
    link->Display();  
    cout<<link->getlen()<<endl;  
    cout<<link->isEmpty()<<endl;  
    cout<<link->Find(3)<<endl;     
    try  
    {  
        cout<<(link->GetNode(10))->data<<endl;  
    }catch(int)  
    {  
        cout<<"所要获取的节点位置超出链表范围"<<endl;  
    }  
    link->Insert(1,888);  
    link->Insert(3,999);  
    link->Delete(6);  
    link->Display();   
    link->Reverse();  
    link->Display();   
    system("pause");  
    return 0;  
}  

### DS单链表删除重复节点的算法实现单链表中删除重复元素是一个经典的链表操作问题。以下是基于题目要求(不可构建新结点,不可定义新链表,在原链表上删除)以及提供的引用内容所描述的方法。 #### 方法概述 为了满足空间复杂度为 O(1),可以选择不借助额外的数据结构如 `HashSet` 来完成此任务。具体方法是对链表中的每个节点作为基准节点,依次向后查找是否有与其值相等的后续节点,并将其移除[^3]。 --- #### 算法步骤说明 通过双指针技术实现该功能: - 定义两个指针变量:`current` 和 `runner`。 - `current` 负责逐一遍历整个链表中的每个节点。 - 对于当前节点 `current` 的值,使用另一个指针 `runner` 向后扫描其后的所有节点,寻找是否存在相同值的节点。 - 如果发现有相同的节点,则调整指针关系以跳过该节点;如果没有则继续向前移动 `runner` 指针。 这种方法的时间复杂度为 O(n²),因为对于每个节点都需要再次遍历它之后的部分链表来检测重复项。 --- #### Python 实现代码 下面是按照上述逻辑编写的 Python 版本程序: ```python class ListNode: def __init__(self, value=0, next=None): self.value = value self.next = next def remove_duplicates(head): current = head while current is not None and current.next is not None: # 当前节点及其下一个均存在时进入循环 runner = current while runner.next is not None: # 使用runner检查后面的节点是否有重复 if runner.next.value == current.value: # 发现有重复值的情况 runner.next = runner.next.next # 移除重复节点 else: runner = runner.next # 继续前进到下一个不同值的位置 current = current.next # 处理完一个节点后转向处理下一位节点 return head # 返回修改过的头节点 # 辅助函数用于打印链表便于验证结果 def print_list(node): result = [] while node is not None: result.append(str(node.value)) node = node.next print(" -> ".join(result)) # 测试用例 if __name__ == "__main__": nodes = [ListNode(i) for i in [1, 2, 3, 2, 4, 5, 3]] for i in range(len(nodes)-1): # 构建初始链表 nodes[i].next = nodes[i+1] print("原始链表:") print_list(nodes[0]) new_head = remove_duplicates(nodes[0]) print("\n去除重复后的链表:") print_list(new_head) ``` --- #### 结果分析 运行以上脚本将会得到如下输出: ``` 原始链表: 1 -> 2 -> 3 -> 2 -> 4 -> 5 -> 3 去除重复后的链表: 1 -> 2 -> 3 -> 4 -> 5 ``` 这表明我们成功地从链表中删除了所有的重复数值[^1]。 --- #### 注意事项 尽管这种解决方案实现了常量级的空间需求 (O(1)) ,但由于嵌套循环的存在使得时间效率较低(O(n²)) 。因此当面对大规模数据集或者性能敏感的应用场景时可能需要考虑其他更高效的策略比如利用哈希集合辅助的方式虽然会增加内存消耗但是能显著提升速度至线性级别即 O(n)。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值