算法练习2之单链表求和

笔试题目:

1、用单向链表表示十进制整数,求两个正整数的和。如下图,1234+34=1268,

注意:单向链表的方向,不允许使用其他的数据结构

题目分析:

题目中提到了,数据结构只能使用单链表,所以数组不在考虑范围之内。

因为将数字转为单链表以后,最高位排在表头,而我们进行整数加法的时候,是从个位开始的,与单链表的顺序相反。所以我们考虑对链表进行反转,然后再做加法。

其中反转和求和的示意图如下:

对求和以后的结果再进行反转:

下面是C++的实现

代码解读

1.节点的数据结构定义如下:

//节点定义
struct Node_t
{
    int m_value;
    Node_t * m_pNext;
};

2. 将int转为List

//int转List
Node_t* IntToNodeList(int value)
{
    Node_t* pHead= new Node_t;
    pHead->m_pNext=nullptr;
    while(value > 0)
    {
        Node_t * pNewNode = new Node_t;
        pNewNode->m_value = value % 10;
        pNewNode->m_pNext = pHead->m_pNext;
        pHead->m_pNext = pNewNode;
        value = value / 10;
    }

    Node_t * pResult = pHead->m_pNext;
    pHead->m_pNext=nullptr;
    delete pHead;
    return pResult;
}

3.将List转为int

//List转int
int NodeListToInt(Node_t* pList)
{
    Node_t * pHead = pList;
    int nResult = 0;
    while(( pHead != nullptr)){
        nResult = nResult*10+pHead->m_value;
        pHead = pHead->m_pNext;
    }
    return nResult;
}

4. 释放节点内存

//释放节点
void FreeNodeList(Node_t* pList)
{
    Node_t* pHead = pList;
    Node_t* pFree = nullptr;
    while(pHead)
    {
        pFree = pHead;
        pHead = pHead->m_pNext;
        delete pFree;
    }
}

5 .实现链表的反转

//链表翻转,使用传入的链表的内存
Node_t* ReverseList(Node_t* pList)
{
    Node_t * pResult = nullptr;
    Node_t * pTem = nullptr;
    while(pList != nullptr)
    {
        pTem = pList->m_pNext;
        pList->m_pNext=pResult;
        pResult= pList;
        pList = pTem;
    }
    return pResult;
}

6.将链表相加

//链表相加
Node_t * AddList(Node_t* pLeft,Node_t* pRight)
{
    Node_t * pRevLeft = ReverseList(pLeft);
    Node_t * pRevRight = ReverseList(pRight);
    Node_t * pResult=nullptr;
    int toUpValue = 0;//进位
    int nLeftValue = 0;
    int nRightValue = 0;

    while(pRevLeft != nullptr || pRevRight != nullptr)
    {
        Node_t * pNewNode = new Node_t;
        pNewNode->m_pNext = pResult;
        pResult = pNewNode;

        nRightValue = 0;
        nLeftValue = 0;

        if(pRevLeft)
        {
            nLeftValue = pRevLeft->m_value;
            pRevLeft = pRevLeft->m_pNext;
        }

        if(pRevRight)
        {
            nRightValue = pRevRight->m_value;
            pRevRight = pRevRight->m_pNext;
        }

        int curPosSum = nRightValue+nLeftValue;
        pNewNode->m_value = curPosSum%10+toUpValue;
        toUpValue = curPosSum/10;
    }
    return pResult;
}

主函数:

int main(int argc,char * argv[])
{
    int nLeftValue = rand();
    int nRightValue = rand();
    std::cout<<"Test Reverst"<<std::endl;
    Node_t * pLeftList = IntToNodeList(nLeftValue);
    Node_t * pRightList = IntToNodeList(nRightValue);
    Node_t * pSumList = AddList(pLeftList,pRightList);
    int nSum = NodeListToInt(pSumList);

    FreeNodeList(pLeftList);
    FreeNodeList(pRightList);
    FreeNodeList(pSumList);
    std::cout<<"TEST "<<nRightValue<<"   "<<nLeftValue <<"           "<<nSum<<std::endl;
    return 0;
}

原文地址:https://www.cnblogs.com/Dennis-mi/p/10326643.html

时间: 2024-10-06 03:46:55

算法练习2之单链表求和的相关文章

算法题:反转单链表

说明:本文仅供学习交流,转载请标明出处,欢迎转载! 题目:存在一个单链表,头指针为head,实现单链表的反转Node *Reverse(Node *head).  该算法的求解办法有很多,如: 方法1:先顺序变量单链表,将结点保存到栈中,在从栈中弹出结点,重新建立一个新的单链表: 方法2:用<剑指offer>里面给出的算法,用三个指针来实现: 方法3:采用递归实现,是方法2的递归实现形式. 本文主要给出方法2和方法3,在给出具体的代码之前,先要注意几个问题:          (1)如果hea

数据结构与算法系列四(单链表)

1.引子 1.1.为什么要学习数据结构与算法? 有人说,数据结构与算法,计算机网络,与操作系统都一样,脱离日常开发,除了面试这辈子可能都用不到呀! 有人说,我是做业务开发的,只要熟练API,熟练框架,熟练各种中间件,写的代码不也能“飞”起来吗? 于是问题来了:为什么还要学习数据结构与算法呢? #理由一: 面试的时候,千万不要被数据结构与算法拖了后腿 #理由二: 你真的愿意做一辈子CRUD Boy吗 #理由三: 不想写出开源框架,中间件的工程师,不是好厨子 1.2.如何系统化学习数据结构与算法?

7. C#数据结构与算法 -- 存储结构(单链表)

C#定义并实现单链表 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Linked {     //单链表结点类,采用泛型       public class Node<T> {         private T data; //数据域,当前结点的数据           private 

算法总结之 在单链表和双链表中删除倒数第k个节点

分别实现两个函数,一个可以删除单链表中倒数第k个节点,另一个可以删除双链表中倒数第k个节点 思路: 如果链表为空,或者k<1 参数无效 除此之外 让链表从头开始走到尾,每移动一步,就让k的值减1 当链表走到头时候 如果k值大于0   说明不用调整  因为链表根本没有倒数第k个节点 此时将原链表直接返回即可 如果k值=0,说明链表倒数第k个节点就是头节点,此时直接返回head.next 也就是原链表的第二个节点 让第二个节点作为链表的头节点,此时直接返回head.next 如果k值<0  重新从

[PTA] 数据结构与算法题目集 6-1 单链表逆转

List Reverse(List L) { List p, q; p = L; q = L; L = NULL; while (p) { p = p->Next; q->Next = L; L = q; q = p; } return L; } 原文地址:https://www.cnblogs.com/ruoh3kou/p/9975225.html

小猪的数据结构辅助教程——2.2 线性表中的单链表

小猪的数据结构辅助教程--2.2 线性表中的单链表 标签(空格分隔): 数据结构 本节学习路线图与学习要点 学习要点: 1.理解顺序表以及单链表各自的有点以及缺点! 2.熟悉单链表的形式,对于头指针,头结点,尾结点,数据域和指针域这些名词要知道是什么! 3.熟悉单链表的结点结构 4.区分头指针与头结点! 5.熟悉创建单链表的两种方式:头插法和尾插法 6.了解单链表12个基本操作的逻辑 7.有趣的算法题:查找单链表的中间结点~ 1.单链表的引入(顺序表与单链表的PK) 2.单链表的结构图以及一些名

Java-找出两个单链表的首个公共节点

单链表中的简单算法 /** * 得到两个单链表的公共结点 * 先求出两个链表的长度,并求出二者的差值dif,两个指针分别指向链表头部,让指向长的链表的指针先向链表尾部移动dif步. * 最后一起一步步移动两个指针,当两个指针都指向同一个结点时,返回那个结点 * @param list1 * @param list2 * @return */ public static ListNode getFirstCommonNode(ListNode list1,ListNode list2){ if(l

4.2.2 算法之美--单链表实现

按照书上的要求实现了一下单链表:单链表的实现可能以前看过几次了:现在想想最主要的几个操作算法应该能够写了吧:遇到的问题: 1. 链表节点写成private;所已给出了访问的接口: 2.模板类的.h和.cpp实现写在同一个文件: 3.感觉以后的数据结构实现还是用纯c的实现好一些:然后书主要是思路 节点类: #ifndef SINGLELIST_LISTNODE_H_ #define SINGLELIST_LISTNODE_H_ template <class T> class ListNode

单链表倒置算法

LinkList reverse(LinkList L)//单链表的倒置算法 { LNode *p,*q; p=L->next; L->next=NULL; while(p) { q=p; p=p->next; q->next=L->next; L->next=q; } return L; }