鱼C论坛

 找回密码
 立即注册
查看: 2166|回复: 10

[已解决]链表问题求解思路

[复制链接]
发表于 2017-3-15 17:26:12 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
创建一个链表,有若干节点。
把第一个节点的值复制到第二个中,第二个节点的值复制到第三个中。直到最后的节点指针为NULL。
也就是把1,2,3,4 变成1,1,2,3
想了好久太笨了想不出来,求指点
最佳答案
2017-3-15 18:27:13
注意:程序有很多地方都没有检查,在要求比较高时,应该做一些适当的检查
^_^
#include <stdio.h>
#include <stdlib.h>

typedef struct node
{
        int data;
        struct node *next;
} List;

List *CreateList(void)
{
        List *ret = (List *)malloc(sizeof(List));
        ret->data = 0;
        ret->next = NULL;

        return ret;
}

void ListAddValue(List *L, int data)
{
        List *list = L;

        while(list->next != NULL)
        {
                list = list->next;
        }

        list->next = (List *)malloc(sizeof(List));
        list->next->data = data;
        list->next->next = NULL;
}

int ListGetValue(List *L, int n)
{
        List *list = L;

        while(n--)
        {
                if(list->next != NULL)
                {
                        list = list->next;
                }
                else
                {
                        return -1;
                }
        }

        return list->next->data; // 第一个结点不存储数据
}

int ListChangeValue(List *L, int n, int newValue)
{
        List *list = L;

        while(n--)
        {
                if(list->next != NULL)
                {
                        list = list->next;
                }
                else
                {
                        return -1;
                }
        }

        list->next->data = newValue;

        return 0;
}

int main(void)
{
        List *list = CreateList();
        int v;

        for(int i = 1; i < 5; i++)
        {
                ListAddValue(list, i);
        }

        // 先打印一下
        for(int i = 1; i < 5; i++)
        {
                printf("%d ", ListGetValue(list, i - 1));
        }
        putchar('\n');


        for(int i = 3; i >= 1; i--)
        {
                v = ListGetValue(list, i - 1);
                ListChangeValue(list, i, v);
        }

        // 再一次打印
        for(int i = 1; i < 5; i++)
        {
                printf("%d ", ListGetValue(list, i - 1));
        }
        putchar('\n');

        return 0;
}
1 2 3 4
1 1 2 3
请按任意键继续. . .
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2017-3-15 17:45:06 | 显示全部楼层

回帖奖励 +5 鱼币

看见最新的问题就跑进来了 结果一看 我还没学到你这里
我想问问你学到现在的部分 学多久了  感觉好难懂啊
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-3-15 18:27:13 | 显示全部楼层    本楼为最佳答案   

回帖奖励 +5 鱼币

注意:程序有很多地方都没有检查,在要求比较高时,应该做一些适当的检查
^_^
#include <stdio.h>
#include <stdlib.h>

typedef struct node
{
        int data;
        struct node *next;
} List;

List *CreateList(void)
{
        List *ret = (List *)malloc(sizeof(List));
        ret->data = 0;
        ret->next = NULL;

        return ret;
}

void ListAddValue(List *L, int data)
{
        List *list = L;

        while(list->next != NULL)
        {
                list = list->next;
        }

        list->next = (List *)malloc(sizeof(List));
        list->next->data = data;
        list->next->next = NULL;
}

int ListGetValue(List *L, int n)
{
        List *list = L;

        while(n--)
        {
                if(list->next != NULL)
                {
                        list = list->next;
                }
                else
                {
                        return -1;
                }
        }

        return list->next->data; // 第一个结点不存储数据
}

int ListChangeValue(List *L, int n, int newValue)
{
        List *list = L;

        while(n--)
        {
                if(list->next != NULL)
                {
                        list = list->next;
                }
                else
                {
                        return -1;
                }
        }

        list->next->data = newValue;

        return 0;
}

int main(void)
{
        List *list = CreateList();
        int v;

        for(int i = 1; i < 5; i++)
        {
                ListAddValue(list, i);
        }

        // 先打印一下
        for(int i = 1; i < 5; i++)
        {
                printf("%d ", ListGetValue(list, i - 1));
        }
        putchar('\n');


        for(int i = 3; i >= 1; i--)
        {
                v = ListGetValue(list, i - 1);
                ListChangeValue(list, i, v);
        }

        // 再一次打印
        for(int i = 1; i < 5; i++)
        {
                printf("%d ", ListGetValue(list, i - 1));
        }
        putchar('\n');

        return 0;
}
1 2 3 4
1 1 2 3
请按任意键继续. . .

评分

参与人数 1荣誉 +1 鱼币 +1 收起 理由
qwe1231069 + 1 + 1 ganxie

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

发表于 2017-3-15 19:59:36 | 显示全部楼层

回帖奖励 +5 鱼币

人造人 发表于 2017-3-15 18:27
注意:程序有很多地方都没有检查,在要求比较高时,应该做一些适当的检查
^_^

你好厉害啊,可以帮我看一下我的代码吗?一加operate函数就不能输出了

不知道为什么operate对指针处理完后头指针位置不对了

#include<stdio.h>

typedef struct Node
{
   int data;
   struct Node * next;

}NODE,*PNODE;

PNODE create_list();
void traverse_list(PNODE);
PNODE operate_list(PNODE);
void main()
{
  PNODE pHead=NULL;
  pHead=create_list();
  operate_list(pHead);
  traverse_list(pHead);
}

PNODE create_list()
{
        int n,i,val;
   PNODE pHead=(PNODE)malloc(sizeof(NODE));
   PNODE pTail=pHead;
   pTail->next=NULL;
   printf("请输入节点数:");
  
   scanf("%d",&n);
   for(i=0;i<n;i++)
   {
    PNODE pNew=(PNODE)malloc(sizeof(NODE));
    pTail->next=pNew;
        printf("请输入第%d个节点的值:",i);
        scanf("%d",&val);
        pNew->data=val;
        pTail=pNew;
        pNew->next=NULL;
   }
   return pHead;
}

void traverse_list(PNODE pHead)
{
  PNODE p=pHead->next;
  while(p!=NULL)
  {
          printf("%d ",p->data);
          p=p->next;
  }
}

PNODE operate_list(PNODE pHead)
{
   int a,b;
  PNODE pTail=pHead;
  PNODE p=pHead->next;
  PNODE pp=p->next;

  pTail->next=NULL;

   
    b=p->data;
  while(pp!=NULL)
  {
   a=pp->data;
   pp->data=b;
   pp=pp->next;
   p=p->next;
   b=a;
  }

}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-3-15 20:09:24 | 显示全部楼层
sunmenmian 发表于 2017-3-15 19:59
你好厉害啊,可以帮我看一下我的代码吗?一加operate函数就不能输出了

不知道为什么operate对指针处理完 ...

无标题.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-3-15 20:32:23 | 显示全部楼层

回帖奖励 +5 鱼币

哈哈,刚学到这课。。。看看你们。学学经验
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-3-16 00:04:10 From FishC Mobile | 显示全部楼层
人造人 发表于 2017-3-15 20:09

啊呀我可能是复制错了,如果这个函数改成void,在主函数中的pHead还指向头吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-3-16 00:18:51 | 显示全部楼层
sunmenmian 发表于 2017-3-16 00:04
啊呀我可能是复制错了,如果这个函数改成void,在主函数中的pHead还指向头吗?

无标题.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

发表于 2017-3-16 03:41:20 | 显示全部楼层

回帖奖励 +5 鱼币

自己的理解的有两个方法,希望大家可以一起进步
新手又犯了低级错误,第二个方法一直报错误,检查了半天,结果就是if()判断那里,把 == 写成了 = ,一直是内存错误,好心塞
#pragma once

#include <stdio.h>
#include <iostream>
#define        MAXSIZE        20
#define        WRONG        -1
#define        OK                0
typedef int ElemType;
typedef int Status;//返回结果

using namespace std;

//链式存储线性表,单链表
typedef class LinkNode* MyLinkList;

class LinkNode
{
public:
        ElemType data;
        LinkNode *next;
public:
        LinkNode() :data(0), next(nullptr) {}
        Status ListCreateTail(MyLinkList *list, int length)
        {
                MyLinkList node, tail;//创建一个临时结点和一个尾结点;

                //(*list) = (MyLinkList)malloc(sizeof(LinkNode));//给头结点开辟空间;
                *list = new LinkNode();//同上,给头结点开辟空间;
                (*list)->data = length;//头结点数据为链表总结点数,不包括头结点;
                tail = *list;//空链表的头结点即尾结点;
                for (int i = 0; i < length; i++)
                {
                        //cout << "第" << i << "个元素" << endl;
                        /*node = (MyLinkList)malloc((sizeof(LinkNode)));
                        node->data = i;
                        node->next = nullptr;*/
                        node = new LinkNode(i);
                        if (node == nullptr)        return        WRONG;

                        tail->next = node;
                        tail = node;
                }
                tail->next = nullptr;
                return OK;
        }
        /*显示链表*/
        Status ListShow(MyLinkList *list)
        {
                MyLinkList tempNode = *list;
                if (!tempNode || tempNode->next == nullptr)
                {
                        cout << "无该链表或者链表为空" << endl;
                        return WRONG;
                }

                cout << "链表中数据为:";
                while (tempNode->next != nullptr)
                {
                        cout << tempNode->data << " ";
                        tempNode = tempNode->next;
                }
                cout << tempNode->data << " ";
                cout << endl;

                return OK;
        }
        /*销毁链表*/
        Status ClearLinkList(MyLinkList* list)
        {
                LinkNode *p,*q;
                p = (*list)->next;
                while (p)
                {
                        q = p->next;
                        delete(p);
                        p = q;
                }
                delete(*list);
                (*list) = nullptr;
                return OK;
        }

        //方法一:依次向后赋值,相当于赋值一份头结点插入到第一个结点前面,再把最后一个结点删除;
        void MyChangeTest(MyLinkList* list)
        {
                LinkNode *tempNode;//临时结点
                LinkNode *head = new LinkNode(**list);//新复制一个头结点

                (*list)->next = head;//链表指向新的头结点
                tempNode = head->next;//临时结点赋值
                if (tempNode->next == nullptr)
                        cout << "空链表" << endl;

                while (tempNode->next->next!=nullptr)//找倒数第二个结点
                {
                        tempNode = tempNode->next;
                }
                delete(tempNode->next);//删除最后一个结点
                tempNode->next->next = nullptr;
                tempNode->next = nullptr;//现在最后一个结点,原倒数第二个结点的next赋空
        }

        //方法二:按照题目要求,依次向后赋值;
        void MyChangeTest2(LinkNode* node,ElemType d)
        {
                if (node->next == nullptr)//递归条件,当结点下一个指向空的时候返回
                {
                        node->data = d;//先赋值再返回
                        return;
                }
                ElemType tempData = node->data;//保存当前结点的数据,用来传给下一个结点
                node->data = d;//当前结点赋值上一个结点传过来的值
                MyChangeTest2((node->next), tempData);//递归
        }
};
int main()
{
        MyLinkList *lklist = new MyLinkList();
        (*lklist)->ListCreateTail(lklist, 10);
        (*lklist)->ListShow(lklist);
        cout << "===============================" << endl;
        (*lklist)->MyChangeTest(lklist);//方法1
        (*lklist)->ListShow(lklist);
        (*lklist)->ClearLinkList(lklist);
        delete(lklist);
        lklist = nullptr;
        cout << "=================================================" << endl;
        MyLinkList *lklist2 = new MyLinkList();
        (*lklist2)->ListCreateTail(lklist2, 10);
        (*lklist2)->ListShow(lklist2);
        cout << "===============================" << endl;
        (*lklist2)->MyChangeTest2((*lklist2), (*lklist2)->data);//方法2
        (*lklist2)->ListShow(lklist2);
        (*lklist2)->ClearLinkList(lklist2);
        delete(lklist2);
        lklist2 = nullptr;

        int pause;
        cin >> pause;
        return 0;
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-3-16 08:21:03 | 显示全部楼层

噗,果然一删好了,想请教一下,pTail和pHead指向同一区域,修改pTail让它指向链表的尾部,会让pHead跟着指向尾部吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-3-16 12:19:37 | 显示全部楼层
sunmenmian 发表于 2017-3-16 08:21
噗,果然一删好了,想请教一下,pTail和pHead指向同一区域,修改pTail让它指向链表的尾部,会让pHead跟着指向 ...

你自己写一个程序测试一下就知道了,我想那样印象更深刻
^_^
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-28 00:37

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表