双向链表,顾名思义就是一个节点有两个方向,一个指向前驱,一个指向后继。
双向链表主要是为了方便查找前驱,但同时也牺牲了一定的空间。
双向链表与循环链表有个相似,就是都能回到起点。(循环链表我不打算写一篇博文介绍,双向链表就是循环链表的一个升级版本,搞懂双向链表,循环链表自然就懂了)。打个比方,有两堆人,各自围成一圈,第一堆人,每个人的左手牵着前面一个人的右手,右手牵着后面一个人的左手,这样围成一个圈可以看作是双向链表。而另一圈人,一个人的双手搭着下一个人的肩,这样围成的一圈,可以看作循环链表。
当然,我们今天只介绍双向链表。搞懂双向,循环自然也就懂了。
下图是双向链表的空间结构,方便大家理解。
这次我实现了几个功能
1.创建链表
2.遍历整个链表
3.获得链表的长度
4.获得链表的最后一个节点(不知道怎么就要写了这个模块,竟然写了就保留着吧)
5.在链表中的指定位置插入指定元素
6.删除指定位置上的元素1.创建链表
D_L_Node *Create_DList(D_L_Node *List) { //创建链表 D_L_Node *Head; D_L_Node *Temp; D_L_Node *Tail; Head = (D_L_Node *)malloc(sizeof(D_L_Node)); Head = List; int Element, Num = 1; cout << "请输入要添加的元素" << endl; cout << "输入第" << Num << "个元素:"; cin >> Element; Head->Date = Element; Head->next = Head; Head->prior = Head; Temp = (D_L_Node *)malloc(sizeof(D_L_Node)); Temp = Head; while (Element != 0) { ++Num; cout << "输入第" << Num << "个元素:"; cin >> Element; if(Element!=0){ //不断的在后面添加新的元素 Tail = (D_L_Node *)malloc(sizeof(D_L_Node)); Tail->Date = Element; Temp->next = Tail; Tail->next = Head; Head->prior = Tail; Tail->prior = Temp; Temp = Tail; } } return List; }
2.遍历整个链表void Output_List(D_L_Node *List) { //遍历整个链表 D_L_Node *p; p = List; int Num = 1; cout << "第" << Num << "个元素:"; cout << p->Date << endl; p = p->next; while (p != List) { Num++; cout << "第" << Num << "个元素:"; cout << p->Date << endl; p = p->next; } }
3.获得链表的长度
4.获得链表的最后一个节点(不知道怎么就要写了这个模块,竟然写了就保留着吧)int Get_Length_L(D_L_Node *List) { //获得链表的长度 int Length=1; D_L_Node *p; p = List; if (List == NULL) return 0; else { while (p->next != List) { Length++; p = p->next; } } return Length; }
5.在链表中的指定位置插入指定元素D_L_Node *Get_Tail_L(D_L_Node *List) { //获得链表的最后一个节点,不知道怎么就要写这个模块,竟然写了就保留着吧 D_L_Node *p; p = List; while (p->next != List) { p = p->next; } return p; }
有张图可以帮助大家理解下
void Insert_L(D_L_Node *List, int Position, int Element) { //在链表中的指定位置插入指定元素 int temp=1; D_L_Node *p,*InsertN; InsertN = (D_L_Node *)malloc(sizeof(D_L_Node)); p = (D_L_Node *)malloc(sizeof(D_L_Node)); p = List; InsertN->Date = Element; InsertN->next = InsertN; InsertN->prior = InsertN; if (Position > Get_Length_L(List) && Position <= 0) { cout << "位置输入有误,请重新输入:"; cin >> Position; } while (temp != Position) { p = p->next; temp++; } p->prior->next = InsertN; InsertN->prior = p->prior; InsertN->next = p; p->prior = InsertN; }
6.删除指定位置上的元素同样有张图
void Delete_L(D_L_Node *List,int Position) { //删除指定位置上的元素 D_L_Node *p; p = List; int n = 1; if (Position > Get_Length_L(List) && Position <= 0) { cout << "位置输入有误,请重新输入:"; cin >> Position; } while (n != Position) { p = p->next; n++; } p->prior->next = p->next; p->next->prior = p->prior; delete p; }
--------------------------------------------------------------------------------华丽的分割线------------------------------------------------------------------------------------------------------下面我列出我用双向链表表达出来的一个数学算式
P(X)=x^a+x^b+.....+x^z+...
就是链表来储存函数各项指数,然后输入x的值,最后得出结果。
其中我用了冒泡排序法(我会在以后专门有一篇文章来介绍各种排序法的)
下面是我的源码以及效果图:
#include<iostream> using namespace std; typedef struct D_L_Node { //Double link Node,双向链接节点 int Date; struct D_L_Node *prior; struct D_L_Node *next; }D_L_Node; D_L_Node *Create_DList(D_L_Node *List) { //创建链表 D_L_Node *Head; D_L_Node *Temp; D_L_Node *Tail; Head = (D_L_Node *)malloc(sizeof(D_L_Node)); Head = List; int Element, Num = 1; cout << "请输入要添加的元素" << endl; cout << "输入第" << Num << "个指数:"; cin >> Element; Head->Date = Element; Head->next = Head; Head->prior = Head; Temp = (D_L_Node *)malloc(sizeof(D_L_Node)); Temp = Head; while (Element != 0) { ++Num; cout << "输入第" << Num << "个指数:"; cin >> Element; if(Element!=0){ //不断的在后面添加新的元素 Tail = (D_L_Node *)malloc(sizeof(D_L_Node)); Tail->Date = Element; Temp->next = Tail; Tail->next = Head; Head->prior = Tail; Tail->prior = Temp; Temp = Tail; } } return List; } void Output_List(D_L_Node *List) { //遍历整个链表 D_L_Node *p; p = List; int Num = 1; cout << "第" << Num << "个元素:"; cout << p->Date << endl; p = p->next; while (p != List) { Num++; cout << "第" << Num << "个元素:"; cout << p->Date << endl; p = p->next; } } int Get_Length_L(D_L_Node *List) { //获得链表的长度 int Length=1; D_L_Node *p; p = List; if (List == NULL) return 0; else { while (p->next != List) { Length++; p = p->next; } } return Length; } D_L_Node *Get_Tail_L(D_L_Node *List) { //获得链表的最后一个节点,不知道怎么就要写这个模块,竟然写了就保留着吧 D_L_Node *p; p = List; while (p->next != List) { p = p->next; } return p; } void Insert_L(D_L_Node *List, int Position, int Element) { //在链表中的指定位置插入指定元素 int temp=1; D_L_Node *p,*InsertN; InsertN = (D_L_Node *)malloc(sizeof(D_L_Node)); p = (D_L_Node *)malloc(sizeof(D_L_Node)); p = List; InsertN->Date = Element; InsertN->next = InsertN; InsertN->prior = InsertN; if (Position > Get_Length_L(List) && Position <= 0) { cout << "位置输入有误,请重新输入:"; cin >> Position; } while (temp != Position) { p = p->next; temp++; } p->prior->next = InsertN; InsertN->prior = p->prior; InsertN->next = p; p->prior = InsertN; } void Delete_L(D_L_Node *List,int Position) { //删除指定位置上的元素 D_L_Node *p; p = List; int n = 1; if (Position > Get_Length_L(List) && Position <= 0) { cout << "位置输入有误,请重新输入:"; cin >> Position; } while (n != Position) { p = p->next; n++; } p->prior->next = p->next; p->next->prior = p->prior; delete p; } void Sort_L(D_L_Node *List) { //整理链表,使其元素呈递增 D_L_Node *p; int Length, temp; int i, j; Length = Get_Length_L(List); for (i = 1; i < Length; i++) { //冒泡排序法 p = List; for (j = 0; j < Length - i; j++) { if (p->Date > p->next->Date) { temp = p->Date; p->Date = p->next->Date; p->next->Date = temp; } p = p->next; } } } void OutPut_P_X(D_L_Node *List) { //输出P(X) D_L_Node *p; int i = 0; int Length = Get_Length_L(List); p = List; cout << "P(X)="; for (i; i < Length; ++i) { cout << "x^" << p->Date; if (p->next != List) cout << "+"; p = p->next; } cout << endl; } int Count_P_X(D_L_Node *List,int X) { //计算P(X) D_L_Node *p; p = List; int Sum = 0,temp; int i, j; for (i = 0; i < Get_Length_L(List); ++i) { temp = 1; for (j = 0; j < p->Date; ++j) { temp *= X; } p = p->next; Sum += temp; } return Sum; } int main() { int Length; D_L_Node *List; D_L_Node *p; int X; List = (D_L_Node *)malloc(sizeof(D_L_Node)); List = Create_DList(List); Sort_L(List); OutPut_P_X(List); cout << "请输入X:"; cin >> X; cout << "P(X)=" << Count_P_X(List, X); system("pause"); return 0; }
效果图
双向链表
最新推荐文章于 2023-12-20 13:35:53 发布