双链表(C/C++)

这段代码涉及了C++中指针的调用和赋值问题,让我们逐步解释这些问题:

  1. 指针参数和引用参数:

    在函数的参数列表中,有一些参数声明为引用类型 LinkList& L。这是 C++ 中的引用参数,用于实现在函数内修改外部变量的值,而无需返回值。对于指针类型参数,通常在函数内部进行动态分配内存或修改指针指向的数据。

    • LinkList& L 表示 L 是一个对 LinkList 类型的引用,也就是一个指向指针的引用。
    • 通过这种方式传递 L 到函数内部,函数可以修改外部 L 指向的链表。
  2. 指针的动态内存分配:

    在函数内部,通过 malloc 函数进行了动态内存分配,如下所示:

    L = (LNode*)malloc(sizeof(LNode));

    这行代码分配了一个新的 LNode 结构体的内存,并将其地址赋值给 L 指针。这样,L 就指向了一个新的链表节点。

  3. 指针的赋值:

    在函数内部,还涉及了对指针的赋值,例如:

    L = (LNode*)malloc(sizeof(LNode));

    这行代码将新分配的节点的地址赋值给 L 指针。这是为了确保 L 指向链表的头节点。

    同样的操作也出现在一些其他函数中,如 List_HeadInsertList_TailInsert,它们都在函数内部修改了 L 指针的值,使其指向新的链表头节点。

  4. 指针的使用和节点遍历:

    在函数中,指针 L 和其它指针 p 被用于遍历链表的节点。例如,在 print 函数中:

     

    LNode* s = L; while (s->next != NULL) { s = s->next; // 一直向后指 cout << s->data << " "; } 这里,s 指针用于遍历链表节点,并打印节点的数据。

  5. 全代码如下

    #include<iostream>
    #include<algorithm>
    
    using namespace std;
    typedef int ElemType;
    typedef struct Dnode {
    
    	ElemType data;
    	struct Dnode* prior, * next;
    }Dnode, * DLinkList;
    //初始化双链表
    bool InitDLinkList(DLinkList& L)
    {
    	L = (Dnode*)malloc(sizeof(Dnode));
    	if (L == NULL)
    	{
    		return false;
    	}
    	L->prior = NULL;
    	L->next = NULL;
    	return true;
    
    }
    //在p节点后面插入值是e的节点
    
    bool InsertNextDNode(Dnode* p, ElemType e)
    {
    	if (p == NULL)
    	{
    		return false;
    	}
    	Dnode* q = (Dnode*)malloc(sizeof(Dnode));
    	if (q == NULL)
    	{
    		return false;
    	}
    	q->data = e;
    	q->next = NULL;
    	q->prior = p;
    	if (p->next != NULL)
    	{
    		p->next->prior = q;
    		q->next = p->next;
    
    	}
    	p->next = q;
    	return true;
    }
    //尾插法
    DLinkList List_TailInsert(DLinkList& L)
    {
    	InitDLinkList(L);//初始化
    
    	Dnode* s, * r = L;
    	int x;
    	cin >> x;
    	while (x != 9999) {
    		s = (Dnode*)malloc(sizeof(Dnode));
    		s->data = x;
    		s->next = NULL;
    		s->prior = r;
    		r->next = s;
    		r = s;
    		cin >> x;
    	}
    	return L;
    }
    //头插法建立双链表
    DLinkList HeadInsert(DLinkList& L) {
    	InitDLinkList(L);//初始化
    	int x;
    	cin >> x;
    	while (x != 9999) {
    		Dnode* s = (Dnode*)malloc(sizeof(Dnode));
    		s->data = x;
    		if (L->next == NULL) {
    			s->next = NULL;
    			s->prior = L;
    			L->next = s;
    		}
    		else {
    			s->next = L->next;
    			L->next->prior = s;
    			s->prior = L;
    			L->next = s;
    		}
    		cin >> x;
    	}
    	return L;
    }
    //判断双链表是否为空
    bool empty(DLinkList L)
    {
    	if (L->next = NULL)
    	{
    		return true;
    	}
    	return false;
    }
    //按位查找,返回第i个节点
    Dnode* GetElem(DLinkList L, int i)
    {
    	if (i < 0)
    	{
    		return NULL;
    	}
    	int j = 0;
    	Dnode* p = L;
    	while (p != NULL && j < i)
    	{
    		p = p->next;
    		j++;
    	}
    	return p;
    
    }
    //按值查找,找到第一个数据域为e的结点
    Dnode* LocateElem(DLinkList L, ElemType e)
    {
    	Dnode* p = L;
    	if (p == NULL)
    	{
    		return NULL;
    	}
    	p = p->next;
    	while (p != NULL && p->data != e)
    	{
    		p = p->next;
    	}
    	return p;
    }
    
    //在p节点之后插入s节点
    bool InsertNextDNode(Dnode* p, Dnode* s)
    {
    	if (p == NULL || s == NULL)
    	{
    		return false;
    	}
    	s->next = p->next;
    	if (p->next != NULL)
    	{
    		p->next->prior = s;
    	}
    	s->prior = p;
    	p->next = s;
    
    	return true;
    
    }
    
    //前插,在p节点前面插入节点s
    bool InsertPriorDnode(Dnode* p, Dnode* s)
    {
    	return InsertNextDNode(p->prior, s);
    
    }
    //按位插入,在第i个位置插入节点s
    bool InsertDlinkList(DLinkList& L, int i, ElemType e)
    {
    	if (i < 0)
    	{
    		return false;
    
    	}
    	Dnode* p = GetElem(L, i - 1);
    	return InsertNextDNode(p, e);
    }
    //删除p节点的后继节点
    bool DeleteNextNode(Dnode* p)
    {
    	if (p == NULL)
    	{
    		return false;
    	}
    	Dnode* q = p->next;
    	if (q == NULL)
    	{
    		return false;
    
    	}
    	p->next = q->next;
    	if (q->next != NULL)
    	{
    		q->next->prior = p;
    	}
    	free(q);
    	return true;
    }
    //销毁双链表
    bool DestoryList(DLinkList& L)
    {
    	while (L->next != NULL)
    	{
    		DeleteNextNode(L);
    	}
    	free(L);
    	L = NULL;
    	return true;
    
    
    }
    //双链表的长度
    int Length(DLinkList L)
    {
    	Dnode* p = L;
    	int len = 0;
    	while (p->next != NULL)
    	{
    		len++;
    		p = p->next;
    
    	}
    	return len;
    }
    //删除指定节点s
    bool DeleteNode(Dnode* s)
    {
    	Dnode* p;
    	p = s->prior;
    	p->next = s->next;
    	if (s->next != NULL)
    	{
    		s->next->prior = p;
    
    	}
    	free(s);
    	return true;
    
    }
    //删除位序为i的节点,e是i的节点的值
    bool ListDelete(DLinkList& L, int i, ElemType& e)
    {
    	if (i <= 0 || i > Length(L))
    	{
    		return false;
    	}
    	Dnode* s;
    	s = GetElem(L, i);//按值查找
    	if (s == NULL)
    	{
    		return false;
    
    	}
    	e = s->data;
    	return DeleteNode(s);//删除指定节点
    
    }
    //遍历双链表
    void print(DLinkList L)
    {
    	Dnode* p = L->next;
    	while (p != NULL)
    	{
    		cout << p->data << " ";
    		p = p->next;
    	}
    	cout << endl;
    
    
    }
    
    int main()
    {
    	DLinkList L;//初始化
    	List_TailInsert(L);//尾插法
    	print(L);
    	cout << "单链表的长度" << Length(L);
    	cout << "第一个元素为" << GetElem(L, 1)->data << endl;
    	cout << "第三个元素为" << GetElem(L, 3)->data << endl;
    	cout << "在第一个位置插入元素0" << endl;
    	InsertDlinkList(L, 1, 0);
    	print(L);
    	int e;
    	ListDelete(L, 1, e);
    	cout << "删除的第一个节点:" << e << endl;
    	print(L);
    
    
    
    	return 0;
    }

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值