指针与链表

真正有用的动态变量很少会是int,double这样的简单类型.相反都是一些复杂类型,比如数组,结构体,或类.结构体或类类型的动态变量通常由一个或多个成员变量,这些变量是指针,可将动态变量连接到其它动态变量.

一.节点

在C++中,节点作为结构或类实现.

struct ListNode
{
string item;
int count;
ListNode *link;
}
typedef ListNode* ListNodePtr;

C++支持箭头操作符: head->count=1; 替代了由圆点操作符和提领操作符组成的(*head).count=2;

C++11引入nullptr.避免因为NULL实际是数字0的造成歧义.

#include <string.h>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
 
void func(int *p)
{
	cout<<"null"<<endl;
}

void func(int p)
{
cout<<0<<endl;	
}
int main(int argc, char** argv)
{
	//func(nullptr);
	func(NULL);
    return 0;
}

二.链表(节点列表)

1.在表头插入节点(头插法)

void headInsert(ListNodePtr& head,int c,string i)
{
	ListNodePtr tempPtr;
	tempPtr=new ListNode;//开辟新节点 
	tempPtr->count=c; 
	tempPtr->item=i;
	tempPtr->link=head;
	head=tempPtr;
}

2.遍历

while(head->link!=NULL)//普通遍历 
	{
	cout<<head->item<<":"<<head->count<<endl;
	head=head->link;	
	}
	
   
//	for(iter=head;iter->link!=NULL;iter=iter->link)//迭代器遍历
//	{  
//		cout<<iter->count<<endl;
//	} 

3.在链表中部插入节点

void insert(ListNodePtr afterMe,int c,string i)
{
	ListNodePtr tempPtr;
	tempPtr=new ListNode;//开辟新节点 
	tempPtr->count=c; 
	tempPtr->item=i;
	
	tempPtr->link=afterMe->link;
	afterMe->link=tempPtr;
}

4.删除节点

void del(ListNodePtr &head,int discardTarget)
{
	ListNodePtr pb,pf;//搜索删除指针 
	pb=head;
	if(head==NULL) cout<<"空链表"<<endl;//处理空列表
	else{
		while(pb->count!=discardTarget&&pb->link!=NULL)
		{
			pf=pb;
			pb=pb->link;
		}
		if(pb->count==discardTarget) 
		{
			 if(pb == head)//找到的节点是头节点
             {
              head = pb->link;
             }
             else//找到的节点是普通节点
             {
              pf->link = pb->link;
             }
            free(pb);
		} 
		else cout<<"未搜索到目标"<<endl;
	} 
}

5.搜索节点

ListNodePtr search(ListNodePtr head,int target)
{
	ListNodePtr here=head;
	if(here==NULL) return NULL;//处理空列表
	else{
		while(here->count!=target&&here->link!=NULL)
		{
			here=here->link;
		}
		if(here->count==target) return here;
		else return NULL;
	} 
}

完整代码如下:

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

struct ListNode
{
string item;
int count;
ListNode *link;
};
typedef ListNode* ListNodePtr;

void headInsert(ListNodePtr& head,int c,string i)
{
	ListNodePtr tempPtr;
	tempPtr=new ListNode;//开辟新节点 
	tempPtr->count=c; 
	tempPtr->item=i;
	tempPtr->link=head;
	head=tempPtr;
}

void insert(ListNodePtr afterMe,int c,string i)
{
	ListNodePtr tempPtr;
	tempPtr=new ListNode;//开辟新节点 
	tempPtr->count=c; 
	tempPtr->item=i;
	
	tempPtr->link=afterMe->link;
	afterMe->link=tempPtr;
}

void del(ListNodePtr &head,int discardTarget)
{
	ListNodePtr pb,pf;//搜索删除指针 
	pb=head;
	if(head==NULL) cout<<"空链表"<<endl;//处理空列表
	else{
		while(pb->count!=discardTarget&&pb->link!=NULL)
		{
			pf=pb;
			pb=pb->link;
		}
		if(pb->count==discardTarget) 
		{
			 if(pb == head)//找到的节点是头节点
             {
              head = pb->link;
             }
             else//找到的节点是普通节点
             {
              pf->link = pb->link;
             }
            free(pb);
		} 
		else cout<<"未搜索到目标"<<endl;
	} 
}

ListNodePtr search(ListNodePtr head,int target)
{
	ListNodePtr here=head;
	if(here==NULL) return NULL;//处理空列表
	else{
		while(here->count!=target&&here->link!=NULL)
		{
			here=here->link;
		}
		if(here->count==target) return here;
		else return NULL;
	} 
}


int main(int argc, char** argv)
{
	ListNodePtr head;//头指针 
	ListNodePtr srhItem;//搜索指针 
	ListNodePtr iter;//迭代器指针
	 
	head=new ListNode;//开辟新节点 	
	
	headInsert(head,200,"学习用品"); 
	headInsert(head,300,"生活用品"); 
	headInsert(head,400,"工作用品"); 

//	insert(head->link->link,900,"总计"); 
//	
//	srhItem=search(head,300);
//	cout<<"查找到该笔款项所对应的花费单元为:"<<srhItem->item<<endl;
	
	
	del(head,100);
	
	while(head->link!=NULL)//普通遍历 
	{
	cout<<head->item<<":"<<head->count<<endl;
	head=head->link;	
	}
//	for(iter=head;iter->link!=NULL;iter=iter->link)//迭代器遍历
//	{  
//		cout<<iter->count<<endl;
//	}     
	return 0;
}

 

三.链表的变体

1.双链表

struct ListNode
{
int data;
ListNode *forwardLink;
ListNode *backLink;
};

2.二叉树

struct TreeNode
{
int data;
TreeNode *leftLink;
TreeNode *rightLink;
};

名为root的指针指向根节点(顶部节点).根节点的作用类似于普通链表的表头节点.跟随连接,可以到达树中的任何节点.

在分支结束的节点中,两个连接变量均设为空,这些节点称为叶节点.

二叉树能够高效存储和检索数据.

四.类构成的链表(Node类)

前面创建链表时,是用struct容纳节点内容,同样地数据结构还有类,基本原理一样.

Node类的接口文件

//头文件node.h,类构成的链表 
namespace linkedlistofclasses
{
	class Node
	{
		public:
			Node();
			Node(int value,Node *next);
			...//之前写的crud方法 
		private:
			int data;
			Node *link; 
	}
	typedef Node* Nodeptr;
};

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值