c++ 链表操作:添加、遍历、删除、查找

       链表是一种动态数据结构,因为在创建链表的时候,无需知道链表的长度。链表的每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。

struct node
{
	int value;
	node* next;
};

当插入一个结点的时候,我们只需要为新结点分配内存,然后调节结点的指针指向,新结点就被(逻辑上)链接到链表里。

/* 链表尾加入新元素*/
node* addNode(node*head ,int addValue)
{
	 node* newNode=new node();
	 newNode->next=NULL;
	 newNode->value=addValue;
	 node* p=new node();
	 p=head; //list的头结点
	 if(head==NULL)
	 {
	   head=newNode; //新节点为链表头节点
	 }else
	 {
		while(p->next!=NULL)//找到尾节点
			p=p->next;
		p->next=newNode; //在尾节点后面加入新节点
	 }
	 return head;
}



由于链表中的内存不是一次性连续分配的,因此我们无法保证链表的内存和数组一样是连续的。因此想在链表中找到它的某一个结点,我们只能从头结点开始,沿着指向下一个结点的指针遍历链表,它的时间效率为O(n)。

/*在链表中找到某个值,删除它*/
node* removeNode(node* head,int value)
{
	node* pNode=head;
	node* deleteNode=NULL;
	if(head==NULL)
	{
	   cout<<"链表为空"<<endl;
	   return NULL;
	}else if(head->value==value)//头节点为目标节点
	{
		deleteNode=head;
		head=head->next;
	}else
	{
	   while(pNode->next!=NULL&&pNode->next->value!=value)//找出目标节点的上一个节点
		 pNode=pNode->next;
	   if(pNode->next!=NULL&&pNode->next->value==value)
	   {
	   deleteNode=pNode->next;
	   pNode->next=pNode->next->next;//删除目标节点
	   }
	}
	 if(deleteNode!=NULL)
	   {
		   delete deleteNode;
		   deleteNode=NULL;
	   }
	return head;
}

从头到尾遍历链表

/*从头到尾遍历链表*/
void travelList(node*head)
{
	node* pNode=head;
	if(head==NULL)
		return ;
	else
	{
	  cout<<pNode->value<<'\t';
	  while(pNode->next!=NULL)
	  {
		  pNode=pNode->next; 
          cout<<pNode->value<<'\t';
	  }
	}  
}

 

从尾到头打印每个结点,我们从头到尾遍历链表,并把每个节点放在stack结构中,利用stack结构先进后出”的特点,从尾到头打印结点。时间复杂度为O(n).

/*从尾到头遍历链表*/
void printNodeReserve(node* head)
{
	stack<node*> nodeStack;
	node * pNode=head;
	if(head==NULL)return ;
	//遍历链表,并把节点保留在stack里
	while(pNode!=NULL)
	{
		nodeStack.push(pNode);
		pNode=pNode->next;
	}
	while(!nodeStack.empty())
	{	
       pNode=nodeStack.top(); //返回top节点
	   cout<<pNode->value<<endl;
	   nodeStack.pop();//删除top节点
	}
}


输出链表中倒数第K个结点。

为了实现一次遍历链表就能找到倒数第K个节点,我们定义两个指针p1,p2。第一个指针p1从链表头指针开始往前走k步,此时,第二个指针p2不动。从第k+1步开始,指针p2也开始头链表头开始遍历,两个指针距离是k.当p1遍历完链表,指向一个null值的时候,p2指针正好是倒数第k个结点。

比如查找倒数第2个指针


//查找链表中倒数第k个节点,并输出
void printKthTOTotal(node *head, int k)
{
	//如果链表为空,或k为0,return 
	if(head==NULL||k<=0) return;
	node* pNode1=head;
	node* pNode2=head;
	//p1指针先往前走k步
	while(k>0&&pNode1!=NULL)
	{
		pNode1=pNode1->next;
		k--;
	}
	//当链表长度小于k,return
	if(k>0)return;
 	while(pNode1!=NULL)
	{
		pNode1=pNode1->next;
		pNode2=pNode2->next;
	}
	cout<<pNode2->value<<endl;
}



/


  • 17
    点赞
  • 63
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是C++实现链表操作的代码: ```c++ #include<iostream> using namespace std; // 定义链表节点 struct ListNode{ int val; ListNode* next; ListNode(int x): val(x), next(NULL){} }; // 链表类 class MyLinkedList{ public: ListNode* head; // 头节点 // 构造函数 MyLinkedList(){ head = new ListNode(0); // 创建头节点 } // 链表清空 void clear(){ ListNode* curr = head->next; while(curr != NULL){ ListNode* temp = curr; curr = curr->next; delete temp; } head->next = NULL; } // 链表初始化 void init(){ clear(); head->next = NULL; } // 遍历链表 void traverse(){ ListNode* curr = head->next; while(curr != NULL){ cout << curr->val << " "; curr = curr->next; } cout << endl; } // 在链表查找节点 ListNode* search(int val){ ListNode* curr = head->next; while(curr != NULL){ if(curr->val == val){ return curr; } curr = curr->next; } return NULL; } // 在链表中插入节点 void insert(int val){ ListNode* node = new ListNode(val); ListNode* curr = head; while(curr->next != NULL && curr->next->val < val){ curr = curr->next; } node->next = curr->next; curr->next = node; } // 在链表删除节点 void remove(int val){ ListNode* curr = head; while(curr->next != NULL){ if(curr->next->val == val){ ListNode* temp = curr->next; curr->next = curr->next->next; delete temp; return; } curr = curr->next; } } }; // 测试 int main(){ MyLinkedList myList; myList.insert(1); myList.insert(3); myList.insert(2); myList.traverse(); // 1 2 3 myList.remove(2); myList.traverse(); // 1 3 return 0; } ``` 以上代码实现了链表的基本操作,你可以根据需要进行调整和修改。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值