qwe1231069 发表于 2017-3-15 17:26:12

链表问题求解思路

创建一个链表,有若干节点。
把第一个节点的值复制到第二个中,第二个节点的值复制到第三个中。直到最后的节点指针为NULL。
也就是把1,2,3,4 变成1,1,2,3
想了好久太笨了想不出来,求指点

屁哥 发表于 2017-3-15 17:45:06

看见最新的问题就跑进来了 结果一看 我还没学到你这里{:9_239:}
我想问问你学到现在的部分 学多久了感觉好难懂啊

人造人 发表于 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
请按任意键继续. . .

sunmenmian 发表于 2017-3-15 19:59:36

人造人 发表于 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;
}

}

人造人 发表于 2017-3-15 20:09:24

sunmenmian 发表于 2017-3-15 19:59
你好厉害啊,可以帮我看一下我的代码吗?一加operate函数就不能输出了

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

赛雷哥 发表于 2017-3-15 20:32:23

哈哈,刚学到这课。。。看看你们。学学经验

sunmenmian 发表于 2017-3-16 00:04:10

人造人 发表于 2017-3-15 20:09


啊呀我可能是复制错了,如果这个函数改成void,在主函数中的pHead还指向头吗?

人造人 发表于 2017-3-16 00:18:51

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

Icetone 发表于 2017-3-16 03:41:20

自己的理解的有两个方法,希望大家可以一起进步
新手又犯了低级错误,第二个方法一直报错误,检查了半天,结果就是if()判断那里,把 == 写成了 = ,一直是内存错误,好心塞{:9_229:}
#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;
}

sunmenmian 发表于 2017-3-16 08:21:03

人造人 发表于 2017-3-16 00:18


噗,果然一删好了,想请教一下,pTail和pHead指向同一区域,修改pTail让它指向链表的尾部,会让pHead跟着指向尾部吗?

人造人 发表于 2017-3-16 12:19:37

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

你自己写一个程序测试一下就知道了,我想那样印象更深刻
^_^
页: [1]
查看完整版本: 链表问题求解思路