这里不对单链表和加法法则以及C/C++的代码细节展开讲解,仅仅给出一个简单的例子。大家参考时候直接看代码即可。
目的:
深入掌握单链表应用的算法设计。
内容:
编写一个程序,完成如下功能:
(1)将用户输入的十进制整数字符串转化为带头结点的单链表每个结点存放一个整数位。
(2)求两个整数单链表相加的结果单链表。
(3)求结果单链表的中间位,如 123 的中间位为 2,1234 的中间位为 2。
# include <iostream>
# include <string>
using namespace std;
//定义链表节点
struct node{
int data;
node* next;
};
//初始化,创建头结点
node* init(){
node* head_node = new node;
head_node->next = NULL;
return head_node;
}
//将输入的数据存入节点当中
node* create_node(int e){
node* newnode = new node;
newnode->data = e;
newnode->next = NULL;
return newnode;
}
//在节点之间建立链接
void create_link(node* head_node, int e){
node* newnode = create_node(e);
newnode->next = head_node->next;
head_node->next = newnode;
}
//销毁链表
void destory_link(node* head_node){
node* pmove = head_node;
while (head_node->next) {
pmove = head_node->next;
head_node->next = pmove->next;
delete(pmove);
}
cout<<"单链表内容已经清空完毕!";
}
//输出链表节点当中存入的数据
void display_link(node* head_node){
node* pmove = head_node->next;
while(pmove != NULL){
cout<<pmove->data;
pmove = pmove->next;
}
}
//将链表之间的元素对应相加
node* add(node* s1, node* s2){
node* head = new node;
node*sum = head;
int count = 0;
while(s1||s2||count){
if(s1) count += s1->data, s1 = s1->next;
if(s2) count += s2->data, s2 = s2->next;
sum->next = create_node(count % 10);
sum = sum->next;
count /= 10;
}
return head->next;
}
//把链表逆序
void reverse(node* head_node){
if(head_node->next == NULL || head_node->next->next == NULL) return;
node* old = head_node->next;
node* next = NULL;
node* reverse = new node;
while(old !=NULL){
next = old->next;
old->next = reverse->next;
reverse->next = old;
old = next;
}
head_node->next = reverse->next;
}
//定义一个快指针和一个慢指针,快指针一次走两个节点
//慢指针一次走一个节点,当快指针指到最后一个节点时,慢指针所指位置即是中点
bool move(node * &p){
if (p->next == NULL) return false;
if (p->next->next == NULL) return false;
if (p->next->next->next == NULL) return false;
p = p->next->next;
return true;
}
int mid(node* head_node){
node* p = head_node;
node* q = head_node;
p = p->next;
while (move(q))
{
p = p->next;
}
return p->data;
}
//开两个链表,存储数据
node* s1 = NULL;
node* s2 = NULL;
//主函数
int main(){
s1 = init();
s2 = init();
//用字符串存入整形数据(存储的是数字对应的ascll码),减去'0'即可取得原来的数字
string a = "123456789101112131415";
string b = "987654321101112131415";
for(int i = 0; i < a.length(); i++) {
//将字符串数据存入链表节点中
create_link(s1,a[i]-'0');
}
for(int i = 0; i < b.length(); i++) {
create_link(s2,b[i]-'0');
}
cout<<"第一个加数是:"<<a<<endl;
cout<<"第二个加数是:"<<b<<endl;
node* result = add(s1,s2);
reverse(result);
cout<<"结果是:";
display_link(result);
cout<<endl;
cout<<"中间的数据是:"<<mid(result);
system("pause");
return 0;
}
输出结果演示:
总结:
1.单链表实现高精度加法的本质其实是模拟我们在小学二年级时候就学过的加法法则。难点在于用链表存取并操作数据。
2.找中位数的时候使用快指针和慢指针的思想,简单而优雅。快指针一次走两步,慢指针一次走一步,当快指针走到末尾时候,慢指针刚好走到中间位置。请学数学的同学给出具体证明,这里地方太小我写不下了。
3.可以用字符串存取位数很大的数字,减去0的ascll码即可得到每位数字的值。