单链表之C++类实现

#include<iostream>
#include<cstdlib>
using namespace std;

typedef int ElemType;

//1.构建结点类
//2.构建单链表类
//3.实现类内函数
//创建、插入、删除、排序、输出

//class Node
//{
//public://若不写属性,默认私有属性
//
//	//公共属性,下面的LinkList()函数可直接赋值,
//	//若设置为私有属性,则要通过在公共属性预留函数进行访问赋值
//	ElemType m_Data;
//	Node* m_Next;
//};

class Node    
{
public:
	void SetData(int data);       //向数据域赋值
	void SetNext(Node* next);     //向指针域赋值
    ElemType	GetData();               //获取数据域内容
	Node* GetNext();             //获取指针域内容

private:
	ElemType m_Data;     //数据域,存放表元素
	Node* m_Next;       //指针域, 指向下一个结点         
};
void Node::SetData(ElemType data)   //向数据域赋值
{
	m_Data = data;
}
void Node::SetNext(Node* next)  //向指针域赋值
{
	m_Next = next;
}
ElemType	Node::GetData()   //获取数据域内容
{
	return m_Data;
}
Node* Node::GetNext()  //获取指针域内容
{
	return m_Next;
}

class LinkList  
{
public:
	LinkList();    //单链表初始化
	~LinkList();   //链表销毁
	bool CreatLinkList(ElemType size);  //创建链表
	void EmptyLinkList();      //测空表
    void LengthLinkList();     //测表长
	void DisplayLinkList();   //输出表元素
    void InsertLinkList();   //在表中第i个位置插入元素
    bool DeleteLinkList();   //删除元素
    void LocateLinkList();   //获取元素
    void GetElemLinkList();  //在链表中查找值为e的元素
    bool ClearLinkList();    //依次释放所有结点,并将头结点指针域置空
    bool SortLinkList();    //排序

private:
	ElemType m_Length;    //长度
	Node* m_Head;        //Node类型  链表头指针
				 //头节点要访问m_Next属性,所以是Node类型
};

//LinkList::LinkList()
//{
//	m_Length = 0;
// 
//	m_Head = new Node;   //申请内存
//	m_Head->m_Data = 0;      //数据域赋值
//	m_Head->m_Next = nullptr;   //指针域赋值
//
//	//m_Head = NULL; //只定义了m_Head的变量,但是没有变量声明和变量实例化
//				  //实际上m_Head = null是这个结点是不存在的
//}

LinkList::LinkList()   //单链表初始化
{
	m_Head = new Node;
	m_Head->SetData(0);
	m_Head->SetNext(nullptr);
	m_Length = 0;
}

LinkList::~LinkList()  //链表销毁: 从头指针开始,依次释放所有结点
{
	Node* p;     //定义一个指向结点的指针p
	while (m_Head) {
		p = m_Head;    //p指针指向头节点,从头节点开始,依次释放结点
		m_Head = m_Head->GetNext();
		delete p;
	}
	m_Head->SetNext(nullptr);  //头结点指向空
}

bool LinkList::CreatLinkList(ElemType size)   //创建链表
{
	Node* pnew, * ptemp;     //设置工作指针,ptemp指向尾结点
	ptemp = m_Head;     
	if (size < 0) {
		cout << "输入结点有误" << endl;
		exit(0);
	}
	for (int i = 0; i < size; i++)
	{
		pnew = new Node;     //新建元素结点
		cout << "请输入第" << i + 1 << "个元素的值" << endl; 
		ElemType k = 0;
		cin >> k;                   //输入新建数据元素值
		pnew->SetData(k);         
		pnew->SetNext(nullptr);   //下一结点设为空指针  //新结点链入表尾
		ptemp->SetNext(pnew);    
		ptemp = pnew;           //ptemp是工作指针
	}
	m_Length = size;
    return true;
}

void LinkList::EmptyLinkList()    //测表空
{
    if (m_Head->GetNext() == NULL)
        cout << "是空表!" << endl;
    else
        cout << "不是空表!" << endl;
}

void LinkList::LengthLinkList()      //测表长
{
	//return m_Length;
    //cout << "表长为:" << m_Length << endl;
	 
	int len = 0;  //计数器初始化
	Node* p;  //设置头指针
	p = m_Head;  //指向头指针
	while (p->GetNext()) {
		len++;
		p = p->GetNext();
	}
	//return len;  //返回表长
    cout << "表长为:" << len << endl;
}

void LinkList::DisplayLinkList()       //输出表元素
{
	Node* p;
	p = m_Head->GetNext();
	int i = 1;
	while (p) {
		cout << "第" << i << "个数据为:" << p->GetData() << endl;
		p = p->GetNext();
		i++;
	}
}

void LinkList::InsertLinkList()  //在表中第i个位置插入元素
{
    int i, e = 0;
    cout << "请输入插入位置:" << endl;
    cin >> i;
    cout << "请输入插入数据:" << endl;
    cin >> e;
    int j = 0;
    Node* p;
    p = m_Head;    //工作指针p指向头结点
    while (p && j < i - 1) {    //查找第i-1个结点
        p = p->GetNext();
        j++;
    }
    if(!p || j>i-1)throw"位置异常";
    else {
        Node* s;
        s = new Node;  //创建新结点
        s->SetData(e);
        s->SetNext(p->GetNext());  //结点s链到p结点之后
        p->SetNext(s);
    }
}

bool LinkList::DeleteLinkList()  //删除元素
{
    ElemType i ,e = 0;   
    int j = 0; //j计数器
    cout << "请输入删除位置:" << endl;
    cin >> i;
    Node* p, * q;
    p = m_Head;   //从头节点开始查找
    while (p->GetNext() && j < i - 1) {
        //p定位到删除结点的前驱
        p = p->GetNext();
        j++;
    }
    if (!p->GetNext() || j > i - 1)throw"位置异常";//删除位置不合理
    else {  //删除位置合理
        q = p->GetNext();   //暂存删除结点位置
        p->SetNext(q->GetNext()); //从链表中摘除删除结点
        e = q->GetData();   //取删除数据元素的值
        cout << "删除的值为:" << e << endl;
        delete q;
        return true;
    }
}

void LinkList::LocateLinkList()   //获取第i个元素的值
{
    int i = 0, j = 1;       //计数器初始化
    cout << "请输入查询位置:" << endl;
    cin >> i;
    Node* p;  //设置工作指针
    p = m_Head->GetNext();  //从首节点开始
    while (p && j < i) {
        p = p->GetNext();
        j++;
    }
    if (!p || j > i) {
        throw "位置异常";
    }
    else {//位置合理
        cout << "获取数值为:" << p->GetData() << endl;
    }
}

void LinkList::GetElemLinkList()  //在链表中查找值为e的元素
{
    int j = 1, e=0;
    cout << "请输入查找的数据:" << endl;
    cin >> e;
    Node* p;
    p = m_Head->GetNext();
    while (p && p->GetData() != e) {
        p = p->GetNext();
        j++;
    }
    if (!p) {//未找到
        cout << "未找到" << endl;
    }
    else {//找到了,返回位序
        cout << "数值位序为:" << j << endl;
    }
}

bool LinkList::ClearLinkList()   //清空单链表
{//依次释放所有结点,并将头结点指针域置空

    Node* p, * q;  //创建指向头结点的指针p,q
    p = m_Head->GetNext();  //下一结点的地址赋值给p

    while (p) { //当p不为空时
        q = p->GetNext();  //p的下一个结点的地址赋给q
        delete p;
        p = q;   //q的地址赋给p
    }
    m_Head->SetData(NULL);  //头结点指针域置空
    return true;
}

bool LinkList::SortLinkList()   //排序
{
    int i = 0;
    Node* p, * q;
    p = m_Head->GetNext(); //p指向首元结点
    while (p != NULL) {
       // 第一重循环将p的位置固定下来,进入第二重循环
       //与后面的遍历指针p所指向的结点之间相互比较大小
        q = p->GetNext();//将q指向p的下一个结点,进行数据之间的大小比较
        while (q != NULL) {
            //第二重循环就是不断将指针q后移,
            //与p所指向的结点数据进行大小比较,数据互换
            if (p->GetData() > q->GetData()) {
                i = p->GetData();//将数据寄存在t中,进行互换
                p->SetData(q->GetData());
                q->SetData(i);
            }
            q = q->GetNext();//遍历
        }
        p = p->GetNext();
    }
    return true;
}

int main()
{
    int i;
    LinkList L;   //建立整形空链表
    
    int choice;
    do
    {
        cout << "1-创建链表\n";
        cout << "2-测表空\n";
        cout << "3-测表长\n";
        cout << "4-显示链表\n";
        cout << "5-插入数据\n";
        cout << "6-删除元素\n";
        cout << "7-获取元素\n";
        cout << "8-查找指定值\n";
        cout << "9-清空单链表\n";
        cout << "10-排序\n";
        cout << "Enter choice:";
        cin >> choice;
        switch (choice)
        {
        case 0://退出
            break;
        case 1://创建链表
            cout << "请输入要创建的链表中元素的个数:";
            cin >> i;
            L.CreatLinkList(i);
            break;
        case 2://测空表
            L.EmptyLinkList();
            break;
        case 3://求表长
            L.LengthLinkList();
            break;
        case 4://显示数据
            L.DisplayLinkList();
            break;
        case 5://插入数据
            L.InsertLinkList();
            break;
        case 6: //删除元素
            L.DeleteLinkList();
            break;
        case 7:   //获取第i个元素的值
            L.LocateLinkList();
            break;
        case 8:  //在链表中查找值为e的元素
            L.GetElemLinkList();
            break;
        case 9:  //清空单链表  
            L.ClearLinkList();
            break;
        case 10://排序
            L.SortLinkList();
            break;
        default://非法选择
            cout << "Invalid choice";
            break;
        }

    } while (choice != 0);

    system("pause");
	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值