添加链表节点、链表的倒序查找、打印
1.其实用的是快慢指针,来倒查某个元素。
#include<iostream>
#include<stdlib.h>
#include<stack>
using namespace std;
typedef int USER_TYPE;//链表中数据用户可以只在这里修改就可以完成
//链表结构
struct ListNode
{
USER_TYPE data;
ListNode* pNext;
};
typedef struct ListNode ListNode;
//创建一个链表结点
ListNode* createListNode(int value)
{
ListNode *pNode = new ListNode();
pNode->data = value;
pNode->pNext = NULL;
return pNode;
}
//遍历链表中的所有结点
void printList(ListNode* pHead)
{
ListNode *pNode = pHead;
while (pNode != NULL)
{
cout << pNode->data << " ";
pNode = pNode->pNext;
}
cout << endl;
}
//输出链表中的某一结点的值
void printListNode(ListNode* pNode)
{
if (pNode == NULL)
{
printf("The node is NULL\n");
}
else
{
printf("The key in node is %d.\n", pNode->data);
}
}
//往链表末尾添加结点
/*
注意这里pHead是一个指向指针的指针,在主函数中一般传递的是引用。
因为如果要为链表添加结点,那么就会修改链表结构,所以必须传递引用才能够保存修改后的结构。
*/
void addToTail(ListNode** pHead, int value)
{
ListNode* pNew = new ListNode();//新插入的结点
pNew->data = value;
pNew->pNext = NULL;
if (*pHead == NULL)//空链表
{
*pHead = pNew;
}
else
{
ListNode* pNode = *pHead;
while (pNode->pNext != NULL)
pNode = pNode->pNext;
pNode->pNext = pNew;
}
}
//对空指针等输入进行判断,鲁棒性更好
ListNode* findKthNodeFromEnd2(ListNode* pHead, int k)
{
if (pHead == NULL || k == 0) //判断指针为空 k == 0的情况;
return NULL;
ListNode* pNode = pHead;//当前结点
ListNode* pKthNode = pHead;//
while (k - 1 > 0)
{
if (pNode->pNext != NULL) //判断 k-1<0的情况
{
pNode = pNode->pNext;//让pNode先走k-1步,快慢指针
--k;
}
else
return NULL;
}
while (pNode->pNext != NULL)
{
pNode = pNode->pNext;
pKthNode = pKthNode->pNext;
}
return pKthNode;
}
void main()
{
//创建结点
ListNode* pNode1 = createListNode(1);//创建一个结点
printList(pNode1);//打印
//往链表中添加新结点
addToTail(&pNode1, 22);//为链表添加一个结点,传入地址用于指针间接修改node之和list
addToTail(&pNode1, 33);//为链表添加一个结点
addToTail(&pNode1, 44);//为链表添加一个结点
addToTail(&pNode1, 55);//为链表添加一个结点
addToTail(&pNode1, 66);//为链表添加一个结点
addToTail(&pNode1, 77);//为链表添加一个结点
//打印链表
printList(pNode1);//打印
//返回第二个指针指向的加点,该节点就是倒数第k个数字
ListNode* KthNode = findKthNodeFromEnd2(pNode1, 2);
printListNode(KthNode);
system("pause");
}
2.单链表逆序的四种思路(数组,栈,逆序链表,递归)
/*************************************************************************
> Function: 链表逆序的四种思路(数组,栈,逆序链表,递归)
************************************************************************/
#include <iostream>
#include <vector>
#include <stack>
#include <stdlib.h>
#include <time.h>
using namespace std;
struct Node
{
int data;
Node *next;
};
//写一个链表类,实现四种链表逆序打印方式(数组,栈,逆序链表,递归)
class LinkList
{
public:
LinkList(){head = new(Node);head->next = NULL;}
void setRandList(int len); //生成len个随机数并插入链表
void insert(int i,int index = 1); //插入,可指定位置,默认头插
void print() const; //打印
void invertPrint_vector() const;//使用数组,不改变链表本身
void invertPrint_stack() const;//使用栈,不改变链表本身
void invertprint_linklist();//直接逆序链表
void invertprint_recursion() const;//递归打印,不改变链表本身
void invertprint_recursion(Node * node) const; //递归时需传参调用该函数
private:
Node * head;
int length = 0;
};
void LinkList::setRandList(int len)
{
srand((unsigned)time(NULL));
for(int i = 0;i < len; i++)
{
insert(rand()%99+1);
}
}
void LinkList::insert(int data,int index)
{
if(index > length + 1)
{
throw "位置出错!";
}
else
{
Node *p = head;
for(int i = 1; i < index; i++)
{
p = p->next;
}
Node *newnode = new Node;
newnode->data = data;
newnode->next = p->next;
p->next = newnode;
length++;
}
}
void LinkList::print() const
{
if(NULL == head->next){return;}
cout << "\n当前正序输出:";
Node *p = head->next;
while(NULL != p)
{
cout << p->data << " ";
p = p->next;
}
cout << endl;
}
void LinkList::invertPrint_vector() const
{
if(NULL == head->next){return;}
cout << "数组倒序:";
vector<int> v;
Node *p = head->next;
while(NULL != p)
{
v.emplace_back(p->data);
p = p->next;
}
for(auto it = v.end() - 1; it >= v.begin(); it--)
{
cout << *it << " ";
}
cout << endl;
}
void LinkList::invertPrint_stack() const
{
if(NULL == head->next){return;}
cout << "栈 倒 序:";
stack<int> s;
Node *p = head->next;
while(NULL != p)
{
s.push(p->data);
p = p->next;
}
while(!s.empty())
{
cout << s.top() << " ";
s.pop();
}
cout << endl;
}
void LinkList::invertprint_linklist()
{
if(NULL == head->next){return;}
cout << "逆序链表(此处使用方法执行过程不打印):\n";
Node *p = new(Node);
p->next = head->next;
Node *q = new(Node);
q->next = p->next->next;
head->next->next = NULL;//必须置空,否则尾节点自循环打印会出错
head->next = q->next->next;
for(int i = 1; i < length - 2; i++)
{
q->next->next = p->next;
p->next = q->next;
q->next = head->next;
head->next = head->next->next;
}
q->next->next = p->next;
head->next->next = q->next;
delete p;
delete q;
}
void LinkList::invertprint_recursion() const
{
if(NULL == head->next){return;}
cout << "递归倒序:";
invertprint_recursion(head);
//本笨蛋目前没想到更好的用一个函数解决该递归的方法,默认参数为head会报错。
//如有大佬,请教我!
cout << endl;
}
void LinkList::invertprint_recursion(Node * node) const
{
if(NULL == node->next)
{
return;
}
invertprint_recursion(node->next);
cout << node->next->data << " ";
//在这里要说明的是,如果把打印放在递归调用前,可以实现正序打印链表
}
int main()
{
LinkList ll;
ll.setRandList(10);
ll.print();
ll.invertPrint_vector();
ll.print();
ll.invertPrint_stack();
ll.print();
ll.invertprint_linklist1();
ll.print();
ll.invertprint_recursion();
ll.print();
ll.invertprint_recursion();
ll.print();
return 0;
}
转载:https://blog.csdn.net/qq_54676460/article/details/119832471

浙公网安备 33010602011771号