11.单链表

1.链表结构

typedef struct _LinkNode
{
	int data; //结点的数据域
	struct _LinkNode* next; //结点的指针域
}LinkNode, LinkList; //LinkList 为指向结构体LNode 的指针类型

2.链表初始化

bool InitList(LinkList*& L)
{
	L = new LinkNode;

	if (!L) return false;//生成节点失败

	L->next = NULL;
	return true;
}

3.插入数据

3.1前插

//前插法
bool ListInsert_front(LinkList* &L, LinkNode *node)
{
	if (!L || !node) return false;

	node->next = L->next;
	L->next = node;
}

3.2尾插

//尾插法
bool ListInsert_back(LinkList*& L, LinkNode* node)
{
	LinkNode* last = NULL;

	if (!L || !node) return false;

	last = L;

	while (last->next) last = last->next;

	node->next = NULL;
	last->next = node;
	return true;
}

3.3任意位置插入元素

//指定位置插入元素
bool LinkInsert(LinkList*& L, int i, int& e)
{
	if (!L) return false;

	int j = 0;//当前位置
	LinkList* p, *s;

	p = L;
	while (p && j < i - 1)//查找位置为i - 1的结点,p指向该结点
	{
		p = p->next;
		j++;
	}

	if (!p || j > i - 1)//无效位置
	{
		return false;
	}

	s = new LinkNode;//生成新节点
	s->data = e;
	s->next = p->next;
	p->next = s;
}

4.打印

//打印
void LinkPrint(LinkList*& L)
{
	LinkNode* p = NULL;

	if (!L)
	{
		cout << "链表为空。";
		return;
	}
	p = L->next;

	while (p)
	{
		cout << p->data << "\t";
		p = p->next;
	}
	cout << endl;
}

5.查询值

5.1按位置查找值

bool Link_GetElem(LinkList* &L, int i, int &e)//单链表的取值
{
	//在带头结点的单链表L中查找第i个元素
	//用e记录L中地i个元素的值
	int index;
	LinkList* p;

	if (!L || !L->next) return false;

	p = L->next;
	index = 1;

	while (p && index < i)//顺向向后扫描,直到p指向第i个元素或p为空
	{
		p = p->next;//p指向下一个结点
		index++;//计数器index相应加1
	}

	if (!p || index > i)
		return false;//i值不合法,i>n或i<=0

	e = p->data;
	return true;
}

5.2按值查找

bool Link_FindElem(LinkList* L, int e, int &index)//按值查找
{
	//在带头结点的单链表L中查找值为e的元素

	LinkList* p;
	p = L->next;
	index = 1;
	if (!L || !L->next)
	{
		index = 0;
		return false;
	}

	while (p && p->data != e)
	{
		p = p->next;
		index++;
	}

	if (!p) 
	{
		index = 0;
		return false;//查无此值
	}

	return true;
}

6.单链表的删除

//单链表的删除
bool LinkDelete(LinkList * &L, int i)
{
	LinkList* p, *q;

	int  index = 0;
	p = L;

	if (!L || !L->next) return false;
	while ((p->next) && (index < i - 1))
	{
		p = p->next;
		index++;
	}

	if (!p->next || (index > i - 1))//当i>n或i<1时,删除位置不合法
	{
		return false;
	}
	q = p->next;//临时保存被删结点的地址以备释放空间
	p->next = q->next;//改变删除结点前驱结点的指针域
	delete q;//释放被删除结点的空间
	return true;
}

7.链表销毁

void LinkDestroy(LinkList*& L)//单链表的销毁
{
	//定义临时结点p指向头结点
	LinkList* p = L;
	cout << "销毁链表!" << endl;

	while (p)
	{
		L = L->next;//L指向下一个结点
		delete p;//删除当前结点
		p = L;//p移向下一个结点
	}
}

完整代码

#include<iostream>
#include<string>
#include<stdlib.h>
using namespace std;

typedef struct _LinkNode
{
    int data; //结点的数据域
    struct _LinkNode* next; //结点的指针域
}LinkNode, LinkList; //LinkList 为指向结构体LNode 的指针类型

bool InitList(LinkList*& L)
{
    L = new LinkNode;
    if (!L) return false;//生成节点失败
    L->next = NULL;
    L->data = -1;
    return true;
}

//前插法
bool ListInsert_front(LinkList*& L, LinkNode* node)
{
    if (!L || !node) return false;
    node->next = L->next;
    L->next = node;
    return true;
}

//尾插法
bool ListInsert_back(LinkList*& L, LinkNode* node)
{
    LinkNode* last = NULL;
    if (!L || !node) return false;
    last = L;
    while (last->next) last = last->next;
    node->next = NULL;
    last->next = node;
    return true;
}

//指定位置插入
bool LinkInsert(LinkList*& L, int i, int& e)
{
    if (!L) return false;
    int j = 0;
    LinkList* p, * s;
    p = L;
    while (p && j < i - 1)
    {
        //查找位置为i-1 的结点,p 指向该结点
        p = p->next;
        j++;
    }
    if (!p || j > i - 1)
    {
        return false;
    }
    s = new LinkNode;//生成新节点
    s->data = e; 
    s->next = p->next;
    p->next = s;
    return true;
}

void LinkPrint(LinkList*& L)
{
    LinkNode* p = NULL;
    if (!L)
    {
        cout << "链表为空." << endl;
        return;
    }
    p = L->next;
    while (p)
    {
        cout << p->data << "\t";
        p = p->next;
    }
    cout << endl;
}

bool Link_GetElem(LinkList*& L, int i, int& e)//单链表的取值
{
    //在带头结点的单链表L 中查找第i 个元素
    //用e 记录L 中第i 个数据元素的值
    int index;
    LinkList* p;
    if (!L || !L->next) return false;
    p = L->next;
    index = 1;

    while (p && index < i)
    {
        //顺链表向后扫描,直到p 指向第i 个元素或p 为空
        p = p->next; //p 指向下一个结点
        index++; //计数器index 相应加1
    }
    e = p->data;
    return true;
}

bool Link_FindElem(LinkList* L, int e, int& index) //按值查找
{
    //在带头结点的单链表L 中查找值为e 的元素
    LinkList* p;
    p = L->next;
    index = 1;
    if (!L || !L->next)
    {
        index = 0;
        return false;
    }
    while (p && p->data != e)
    {
        p = p->next;
        index++;
    }
    if (!p)
    {
        index = 0;
        return false;//查无此值
    }
    return true;
}

bool LinkDelete(LinkList*& L, int i) //单链表的删除
{
    LinkList* p, * q;
    int index = 0;
    p = L;
    if (!L || !L->next)
    {
        return false;
    }
    while ((p->next) && (index < i - 1))
    {
        p = p->next;
        index++;
    }
    if (!p || index > i)
    {
        return false; //i 值不合法,i>n 或i<=0
    }
    if (!p->next || (index > i - 1))
    {
        //当 i>n 或 i<1 时,删89除7位94置38不40合1理111
        return false;
    }
    q = p->next; //临时保存被删结点的地址以备释放空间
    p->next = q->next;//改变删除结点前驱结点的指针域
    delete q; //释放被删除结点的空间
    return true;
}
void LinkDestroy(LinkList*& L) //单链表的销毁
{
    //定义临时节点p 指向头节点
    LinkList* p = L;
    cout << "销毁链表!" << endl;
    while (p)
    {
        L = L->next;//L 指向下一个节点
        cout << "删除元素: " << p->data << endl;
        delete p; //删除当前节点
        p = L; //p 移向下一个节点
    }
}
int main(void)
{
    LinkList* L = NULL;
    LinkNode* s = NULL;
    //1. 初始化一个空的链表
    InitList(L);
    //2. 使用前插法插入数据
    /*int n;
    cout<<"前插法创建单链表"<<endl;
    std::cout<<"请输入元素个数n:";
    cin>>n;
    cout<<"\n 请依次输入n 个元素:" <<endl;
    while(n>0)
    {
        s = new LinkNode; //生成新节点s
        cin>>s->data;
        ListInsert_front(L, s);
        n--;
    }
    */
    //3. 使用尾插法插入数据
    /*
    
    
    int n;
    cout<<"尾插法创建单链表"<<endl;
    std::cout<<"请输入元素个数n:";
    cin>>n;
    cout<<"\n 请依次输入n 个元素:" <<endl;
    while(n>0)
    {
        s = new LinkNode; //生成新节点s    
        cin>>s->data;     
        ListInsert_back(L, s);
        n--;
    }
    */
    //4. 单链表的输出
    LinkPrint(L);
     
     //5.任意位置插入元素
    for (int j = 0; j < 3; j++) 
    {
        int i, x;
        cout << "请输入插入的位置和元素(用空格隔开):";
        cin >> i;
        cin >> x;
        if (LinkInsert(L, i, x)) {
            cout << "插入成功.\n\n";
        }
        else {
            cout << "插入失败!\n\n";
        }
        LinkPrint(L);
    }

    //6. 单链表根据位置获取元素
    int element = 0;
    if (Link_GetElem(L, 2, element)) 
    {
        cout << "获取第二个元素成功, 值:" << element << endl;
    }
    else 
    {
        cout << "获取第二个元素失败!" << endl;
    }
    //7. 单链表根据值查询元素所在的位置
    int index = 0;
    if (Link_FindElem(L, 10, index))
    {
        cout << "查找元素10 存在,所在位置: " << index << endl;
    }
    else 
    {
        cout << "不存在元素10." << endl;
    }
    //8. 单链表删除元素
    if (LinkDelete(L, 2))
    {
        cout << "删除第2 个元素成功!" << endl;
        LinkPrint(L);
    }
    else 
    {
        cout << "删除第2 个元素失败!" << endl;
    }
    //9. 销毁单链表
    LinkDestroy(L);
    system("pause");
    return 0;
}

参考资料:

奇牛学院

posted @ 2023-06-25 21:57  CodeMagicianT  阅读(22)  评论(0编辑  收藏  举报