输入一个链表,按链表值从尾到头的顺序返回一个ArrayList。
/**
* struct ListNode {
* int val;
* struct ListNode *next;
* ListNode(int x) :
* val(x), next(NULL) {
* }
* };
*/
// 头插思路:
class Solution {
public:
vector<int> printListFromTailToHead(ListNode* head) {
vector <int> value;
while (head != NULL)
{
value.insert(value.begin(), head->val);
if (head->next != NULL)
{
head = head->next;
}
else
break;
}
return value;
}
};
// 栈思路:
class Solution {
public:
vector<int> printListFromTailToHead(ListNode* head) {
vector<int> value;
ListNode *p=NULL;
p=head;
stack<int> stk;
while(p!=NULL){
stk.push(p->val);
p=p->next;
}
while(!stk.empty()){
value.push_back(stk.top());//栈顶的元素
stk.pop();//将栈顶的元素弹出,栈顶指针指向下一个元素
}
return value;
}
};
// 翻转思路:
class Solution {
public:
vector<int> printListFromTailToHead(ListNode* head) {
vector<int> value;
ListNode *p=NULL;
p=head;
while(p!=NULL){
value.push_back(p->val);
p=p->next;
}
reverse(value.begin(),value.end());
return value;
}
};
// 递归思路:
class Solution {
public:
vector<int> value;
vector<int> printListFromTailToHead(ListNode* head) {
ListNode *p=NULL;
p=head;
if(p!=NULL){
if(p->next!=NULL){
printListFromTailToHead(p->next);
}
value.push_back(p->val);
}
return value;
}
};
链表的两部分:(1)数据部分:保存的是改结点的实际数据。(2)保存的是下一个结点的地址。一种动态存储分配的结构。用户可以malloc函数动态分配结点的存储空间,当删除某个结点时,应该使用free函数释放其占用的内存空间。链表的缺点——浪费存储空间。
链表的基本操作
//准备数据
typedef struct
{
char key[10];
char name[20]; //关键字
int age;
}Data;
typedef struct Node
{
Data nodeData;
struct Node *nextNode;
}CLType; //定义了链表数据元素的类型Data及链表的数据结构CLType,结点的具体数据保存在一个结构Data中,而指针nextNode用来指向下一个结点。
//追加结点
CLType *CLAddEnd(CLType *head,Data nodeData)
{
CLType *node,*htemp;
if(!(node=(CLType *)malloc(sizeof(CLType))))
{
printf("申请内存失败!"\n);
return NULL;
}
else
{
node->nodeData=nodeData;
node->nextNode=NULL;
if(head==NULL)
{
head=node;
return head;
}
htemp=head;
while(htemp->nextNode!=NULL)
{
htemp=htemp->nextNode;
}
htemp->nextNode=node;
return head;
}
}
//插入头结点
CLType *CLAddFirst(CLType *head,Data nodeData)
{
CLType *node;
if(!(node=(CLType *)malloc(sizeof(CLType))))
{
printf("申请内存失败!"\n);
return NULL;
}
else
{
node->nodeData=nodeData;
node->nextNode=head;
head=node;
return head;
}
}
//查找结点
CLType *CLFindNode(CLType *head,char *key)
{
CLType *htemp;
htemp=head;
while(htemp)
{
if(strcmp(htemp->nodeData.key,key)==0)//若结点关键字与传入的关键字相同
{
return htemp;
}
htemp=htemp->nextNode;
}
return NULL;
}
//插入结点
CLType *CLInsertNode(CLType *head,char *findkey,Data nodeData)
{
CLType *node,*nodetemp;
if(!(node=(CLType *)malloc(sizeof(CLType))))
{
printf("申请内存失败!"\n);
return NULL;
}
node->nodeData=nodeData;
nodetemp=CLFindNode(head,findkey);
if(nodetemp)
{
node->nextNode=nodetemp->nextNode;//新插入的结点指向关键结点的下一个结点
nodetemp->nextNode=node;//设置关键结点指向新插入结点
}
else
{
printf("未找到正确的插入位置!"\n);
free(node);
}
return head;
}
//删除结点
CLType *CLDeleteNode(CLType *head,char *key)
{
CLType *node,*htemp;
htemp=head;
node=head;
while(htemp)
{
if(strcmp(htemp->nodeData.key,key)==0)
{
node->nextNode=htemp->nextNode;
free(htemp);
return 1;
}
else
{
node=htemp;
htemp=htemp->nextNode;
}
}
return 0;
}
//计算链表长度
int CLLength(CLType *head)
{
CLType *htemp;
int Len=0;
htemp=head;
while(htemp)
{
Len++;
htemp=htemp->nextNode;
}
return Len;
}
//显示所有结点
void CLAllNode(CLType *head)
{
CLType *htemp;
Data nodeData;
htemp=head;
printf("当前链表共有%d个结点,链表的所有数据如下:\n",CLLength(head));
while(htemp)
{
nodeData=htemp->nodeData;
printf("结点(%s,%s,%d)\n",nodeData.key,nodeData.name,nodeData.age);
htemp=htemp->nextNode;
}
}