C++链表
主要内容来源于CSDN博客并加以整理。
链表的理解
你现在有一个小纸条,上面写着一个抽屉的地址,那个抽屉里有一些你需要的东西,和一个新的写着地址的小纸条,这个小纸条又指向了一个新的抽屉。
需要的头文件
#include<iostream>
#include<cstdlib>
#include<ctime> //随机链表才需要
#include <string>
using namespace std;
建立链表节点结构
建立一个简单的链表结构可以写为:
struct listpoint
{
int data;
listpoint *next;
};
这里的int data
是一个int数字,也就是我们的数据;而listnode*next
是指向下一个链表节点的指针。可以有指向下一个节点的指针的话,自然也可以有指向上一个节点的指针listnode *last
;
struct listpoint
{
int data;
listpoint *next;
listpoint *last;
};
同样的,在一个指针节点上不仅仅可以放一个数,也可以是一个结构体,比如这里定义了一个结构体mydata
用于存放一个学生的学号,姓名,性别信息:
struct mydata
{
int number;
char name[20];
char sex[20];
};
struct listpoint
{
mydata *information;
listpoint *next;
listpoint *last;
};
创建一个链表
创建基础链表
listpoint *create_normal_list(int n)
{
listpoint *head, *normal, *end;
head = (listpoint*)malloc(sizeof(listpoint));
head->information = (mydata*)malloc(sizeof(mydata));
end = head;
for (int i = 0; i<n; i++)
{
normal = (listpoint*)malloc(sizeof(listpoint));
normal->information = (mydata*)malloc(sizeof(mydata));
cout << "input the number :";
cin >> normal->information->number;
cout << "input the name :";
cin >> normal->information->name;
cout << "input the sex :";
cin >> normal->information->sex;
cout << "----------------------------------" << endl;
end->next = normal;
normal->last = end;
end = normal;
}
end->next = NULL;
head->last = NULL;
return head;
}
首先,链表有头,尾,中间节点,用listpoint *head, *normal, *end;
表示这样的节点。然后用head = (listpoint*)malloc(sizeof(listpoint));head->information = (mydata*)malloc(sizeof(mydata));
这两句,初始化一片地址出来。然后让最后一个节点为头节点,因为通过指针可以直接对地址上的东西进行操作,此时end和head指向同一个地址,对end所指向地址进行操作,等同于对head地址所做的操作。在循环体中,初始化中间节点的地址,然后赋值。向end的下一个节点添加这个normal节点。并且新节点的上一个节点就是end,然后,这个新节点变成了最后一个节点。在最后,链表的最后一个节点的下一个节点为空,头节点的前一个节点为空。最后返回头节点就可以了。
环状链表
前面的操作差不多,在最后只需要把链表首尾相连即可。最后的end->next = NULL;head->last = NULL;
换成:
end->next=head;
head->last=end;
修改链表
修改数数据可以直接通过指针修改地址上的信息。创建一个新的链表p
并指向传入的list
,然后通过n次的p=p->next
移动到需要修改的节点,然后更新信息。
void change_point(listpoint *list,int n,data *information)
{
listpoint *p;
p=list;
for(int i=0;i<n;i++)
{
p=p->next;
}
p->information=information;
}
删除节点,找到需要删除的节点,然后让上一个节点的后面一个节点链接到当前节点的后面一个节点,当前节点的后面一个节点的前一个节点链接到当前节点的上一个节点。
void delete_point(listpoint *list,int n)
{
listpoint *p;
p=list;
for(int i=0;i<n;i++)
{
p=p->next;
}
p->last->next=p->next;
p->next->last=p->last;
free(p);
}
插入节点:假设节点为 p 1 , p 2 , p 3 p_1,p_2,p_3 p1,p2,p3要在 p 2 p_2 p2处插入 p s p_s ps,得到的结果为 p 1 , p 2 , p s , p 3 p_1,p_2,p_s,p_3 p1,p2,ps,p3。
void insert_point(listpoint *list,int n,data *ifmation)
{
listpoint *p;
p=list;
for(int i=0;i<n-1;i++)
{
p=p->next;
}
listpoint *insertpoint;
insertpoint=(listpoint*)malloc(sizeof(listpoint));
insertpoint->information=ifmation;
insertpoint->next=p->next;
p->next->last=insertpoint;
p->next=insertpoint;
insertpoint->last=p;
}
搜寻节点:
listpoint *search_point(listpoint *list,int n)
{
listpoint *p;
p=list;
for(int i=0;i<n;i++)
{
p=p->next;
}
return p;
}
输出数据
输出一个节点:
void output_point(listpoint *point)
{
cout<<"the number is :"<<point->information->number<<endl;
cout<<"the name is :"<<point->information->name<<endl;
cout<<"the sex is :"<<point->information->sex<<endl;
cout<<"----------------------------------"<<endl;
}
输出整个链表数据:
void output_list(listpoint *point)
{
listpoint *p;
p=point;
cout<<endl<<endl<<endl;
while((p=p->next)!=NULL)
{
output_point(p);
}
}
输出部分链表,由于链表得到的都是第一个节点的地址,所以需要移动到当前需要删除的节点然后再删除。
void output_list_part(listpoint *list,int m,int n)
{
int difference=n-m;
listpoint *p;
p=list;
cout<<endl<<endl<<endl;
for(int i=0;i<m;i++)
{
p=p->next;
}
for(int i=0;i<difference+1;i++)
{
output_point(p);
p=p->next;
}
}
整体测试代码,里面有2个函数暂时没有用到,没有介绍。
#include "stdafx.h"
#include<iostream>
#include<cstdlib>
#include<ctime>
#include <string>
using namespace std;
struct mydata
{
int number;
char name[20];
char sex[20];
};
struct listpoint
{
mydata *information;
listpoint *next;
listpoint *last;
listpoint *branch;
};
/********************************************************/
listpoint *create_normal_list(int n)
{
listpoint *head, *normal, *end;
head = (listpoint*)malloc(sizeof(listpoint));
head->information = (mydata*)malloc(sizeof(mydata));
end = head;
for (int i = 0; i<n; i++)
{
normal = (listpoint*)malloc(sizeof(listpoint));
normal->information = (mydata*)malloc(sizeof(mydata));
cout << "input the number :";
cin >> normal->information->number;
cout << "input the name :";
cin >> normal->information->name;
cout << "input the sex :";
cin >> normal->information->sex;
cout << "----------------------------------" << endl;
end->next = normal;
normal->last = end;
end = normal;
}
end->next = NULL;
head->last = NULL;
return head;
}
listpoint *create_loop_list(int n)
{
listpoint *head, *normal, *end;
head = (listpoint*)malloc(sizeof(listpoint));
head->information = (mydata*)malloc(sizeof(mydata));
end = head;
for (int i = 0; i<n; i++)
{
normal = (listpoint*)malloc(sizeof(listpoint));
normal->information = (mydata*)malloc(sizeof(mydata));
cout << "input the number :";
cin >> normal->information->number;
cout << "input the name :";
cin >> normal->information->name;
cout << "input the sex :";
cin >> normal->information->sex;
cout << "----------------------------------" << endl;
end->next = normal;
normal->last = end;
end = normal;
}
end->next = head;
head->last = end;
return head;
}
listpoint *create_random_branch_list(int n)
{
listpoint *search_point(listpoint *list, int n);
listpoint *head;
head = create_normal_list(n);
listpoint *p, *bp;
p = head;
srand((int)(time(NULL)));
int randnum;
while ((p = p->next) != NULL)
{
randnum = rand() % n + 1;
bp = search_point(head, randnum);
p->branch = bp;
}
return head;
}
listpoint *create_random_sort_list(int n)
{
listpoint *head;
head = create_normal_list(n);
listpoint *p1, *p2;
int n1 = 0;
int n2 = n;
srand((int)(time(NULL)));
int randnum;
while (n2 != 1)
{
p1 = head;
p2 = head;
randnum = rand() % n2 + 1 + n1;
for (int i = 0; i<randnum; i++)
{
p2 = p2->next;
}
for (int i = 0; i<n1; i++)
{
p1 = p1->next;
}
if (randnum == n)
{
p2->last->next = NULL;
}
else
{
p2->next->last = p2->last;
p2->last->next = p2->next;
}
p1->next->last = p2;
p2->next = p1->next;
p1->next = p2;
p2->last = p1;
n1 += 1;
n2 -= 1;
}
return head;
}
/********************************************************/
void change_point(listpoint *list, int n, mydata *ifmation)
{
listpoint *p;
p = list;
for (int i = 0; i<n; i++)
{
p = p->next;
}
p->information = ifmation;
}
void delete_point(listpoint *list, int n)
{
listpoint *p;
p = list;
for (int i = 0; i<n; i++)
{
p = p->next;
}
p->last->next = p->next;
p->next->last = p->last;
free(p);
}
void insert_point(listpoint *list, int n, mydata *ifmation)
{
listpoint *p;
p = list;
for (int i = 0; i<n - 1; i++)
{
p = p->next;
}
listpoint *insertpoint;
insertpoint = (listpoint*)malloc(sizeof(listpoint));
insertpoint->information = ifmation;
insertpoint->next = p->next;
p->next->last = insertpoint;
p->next = insertpoint;
insertpoint->last = p;
}
listpoint *search_point(listpoint *list, int n)
{
listpoint *p;
p = list;
for (int i = 0; i<n; i++)
{
p = p->next;
}
return p;
}
void output_point(listpoint *point)
{
cout << "the number is :" << point->information->number << endl;
cout << "the name is :" << point->information->name << endl;
cout << "the sex is :" << point->information->sex << endl;
cout << "----------------------------------" << endl;
}
void output_list(listpoint *point)
{
listpoint *p;
p = point;
cout << endl << endl << endl;
while ((p = p->next) != NULL)
{
output_point(p);
}
}
void output_list_part(listpoint *list, int m, int n)
{
int difference = n - m;
listpoint *p;
p = list;
cout << endl << endl << endl;
for (int i = 0; i<m; i++)
{
p = p->next;
}
for (int i = 0; i<difference + 1; i++)
{
output_point(p);
p = p->next;
}
}
/***************************************************************/
int main()
{
listpoint *head;
head = create_random_sort_list(2);
output_list(head);
system("pause");
return 0;
}
还有一个方面是两个链表合并为一个:
struct ListNode
{
int num;
ListNode *next;
};
ListNode * merge_list(ListNode *p1, ListNode *p2)
{
if (p1==NULL)
{
return p2;
}
if (p2==NULL)
{
return p1;
}
ListNode *head = NULL;
if (p1->num < p2->num)
{
head = p1;
head->next = merge_list(p1->next, p2);
}
else
{
head = p2;
head->next = merge_list(p1, p2->next);
}
return head;
}
ListNode* create_ListNode(int*a,int n)
{
ListNode *head, *normal, *end;
head = (ListNode*)malloc(sizeof(ListNode));
end = head;
head->num = a[0];
for (int i = 1; i < n; i++)
{
normal = (ListNode*)malloc(sizeof(ListNode));
normal->num = a[i];
end->next = normal;
end = normal;
}
end->next = NULL;
return head;
}
void output_Node(ListNode *point)
{
cout << "the number is :" << point->num << endl;
cout << "----------------------------------" << endl;
}
void output_ListNode(ListNode *point)
{
ListNode *p;
p = point;
cout << endl << endl << endl;
while (p != NULL)
{
output_Node(p);
p = p->next;
}
}
/***************************************************************/
int main()
{
int a[5] = { 1,2,3,4,5 };
int b[4] = { 3,4,5,6 };
ListNode *p1 = create_ListNode(a, 5);
output_ListNode(p1);
ListNode *p2 = create_ListNode(b, 4);
output_ListNode(p2);
ListNode *merged = merge_list(p1, p2);
output_ListNode(merged);
system("pause");
return 0;
}