编程C本: 帖子 14 – 双向链表
内容
双链表是一个链表的格式,但与元件前面并在列表如下它的每个元素相关联的
1 安装列表
的结构 1 节点的双向链表类似的列表,以DSLKD,但更多的是指向前节点
typedef int item; typedef struct Node //cau truc 1 Node { item Data; //du lieu cua Node Node *Left; //Con tro trai Node *Right; //con tro phai }; typedef struct DList //cau truc Cua List { Node *Head; //con tro dau Node *Tail; //con tro cuoi };
这样DSLKD DSLKK的结构没有 1 指向第一个DS, 但是DSLKK外指针列表仍进一步 1 节点指针列表的末尾
2 初始化和检查空
它被初始化为 2 开始和结束指针返回NULL, 当测试执行只看到一个空的头指针NULL指针是不够的
void Init(DList &L) { L.Head = NULL; // Con tro dau tro den NULL L.Tail = NULL; // Con tro cuoi tro den NULL } int Isempty (DList L) //kiem tra DS rong { return (L.Head == NULL); }
3. 列表的长度
找到DSLKK的长度,我们绝对可以做到像DSLKD, 从开始的即时审批指针完成, 但我们可以用DSLKK 2 光标在开始和计数结束
int Len (DList L) // Do dai danh sach { Node *PH = L.Head, *PT = L.Tail; //tao Node PH (con tro duyet tu dau DS) và PT (con tro duyet tu cuoi DS) de duyet danh sach L int i = 0; //bien dem if (PH != NULL) i = 1; while (PH != NULL) //trong khi P chua tro den NULL (cuoi danh sach thi lam) { if (PH == PT) break; PH = PH->Right; //cho PH tro den Node tiep theo i++; if (PH == PT) break; PT = PT->Left; //cho PT tro den Node truoc do i++; } return i; //tra lai so Node cua L }
4. 创建 1 节点P包含的信息
Node *Make_Node (item x) //tao 1 Node P chua thong tin la x { Node *P = (Node *) malloc (sizeof (Node)); //Cap phat vung nho cho P P->Data = x; //Ghi du lieu vao Data P->Left = NULL; P->Right = NULL; return P; }
5. 插入元件到第一位置
插入列表的顶部之前,以检查是否该列表为空或不. 如果我们空单的头和尾都指向P. 如果没有执行插入空.
void Insert_first (DList &L, item x) //Chen x vao vi tri dau tien trong danh sach { Node *P; P = Make_Node(x); //tao 1 Node P if (Isempty(L)) //Neu danh sach rong { L.Head = P; L.Tail = P; } else { P->Right = L.Head; L.Head->Left = P; L.Head = P; } }
6. 插入所述列表中的元素的末尾类似于列表
void Insert_last (DList &L, item x) //Chen x vao vi tri cuoi trong danh sach { Node *P; P = Make_Node(x); //tao 1 Node P if (Isempty(L)) //Neu danh sach rong { L.Head = P; L.Tail = P; } else { L.Tail->Right = P; //ket noi voi danh sach P->Left = L.Tail; //P tro ve Node truoc L.Tail = P; //luu lai vi tri cuoi } }
7. 插入元素到位置k
在地方插入前检查位置kķ匹配, 是所述列表或多个列表的末尾. 如果列表我跟随之间插入 4 步骤
void Insert_k (DList &L, item x, int k) //chen x vao vi tri k trong danh sach { Node *PH = L.Head, *PT, *R; int i=1, l = Len(L); if (k<1 || k> l+1) printf("Vi tri chen khong hop le !"); //kiem tra dieu kien else { R = Make_Node(x); //tao 1 Node P if (k == 1) Insert_first(L,x); //chen vao vi tri dau tien else if (k == l+1) Insert_last(L,x); //chen vao vi tri cuoi else //chen vao vi tri 1<k<l+1 { while (PH != NULL && i != k-1) //duyet den vi tri k-1 { i++; PH = PH->Right; } PT = PH->Right; //xac dinh vi tri k R->Right = PT; //(1) R->Left = PH; //(2) PH->Right = R; //(3) PT->Left = R; //(4) } } }
8. 除去第一元件, 列表的末尾
// Lay gia tri can xoa ra, sau do bo qua 1 Node dau tien void Del_first (DList &L, item &x) //Xoa phan tu dau tien { if (!Isempty(L)) { x = L.Head->Data; //lay gia tri ra neu can dung L.Head = L.Head->Right; //Cho L tro den Node thu 2 trong danh sach } } // Lay gia tri can xoa ra, sau do bo qua 1 Node cuoi void Del_last (DList &L, item &x) //Xoa phan tu dau tien { if (!Isempty(L)) { x = L.Tail->Data; L.Tail = L.Tail->Left; L.Tail->Right = NULL; } }
9. 在位置k删除元素
删除到位前检查位置kķ匹配, 是所述列表或多个列表,或结束时在中间
void Del_k (DList &L, item &x, int k) //Xoa Node k trong danh sach { Node *PH = L.Head, *PT; int i=1, l = Len(L); if (k<1 || k> l) printf("Vi tri xoa khong hop le !"); //kiem tra dieu kien else { if (k == 1) Del_first(L,x); //xoa vi tri dau tien else if (k == l) Del_last(L,x); //xoa vi tri cuoi else //xoa vi tri 1<k<l+1 { while (PH != NULL && i != k-1) //duyet den vi tri k-1 { i++; PH = PH->Right; } x = PH->Right->Data; PT = PH->Right->Right; //xac dinh vi tri k+1 PH->Right = PT; PT->Left = PH; } } }
10. 查找元素x在DS
int Search (DList L, item x) //tim x trong danh sach { Node *P=L.Head; int i=1; while (P != NULL && P->Data != x) //duyet danh sach den khi tim thay hoac ket thuc danh sach { P = P->Right; i++; } if (P != NULL) return i; //tra ve vi tri tim thay else return 0; //khong tim thay }
11. 在DS删除元素x
void Del_x (DList &L, item x) //xoa phan tu x trong danh sach { int l = Search(L,x); while (l) { Del_k (L,x,l); //trong khi van tim thay x thi van xoa l = Search(L,x); } }
12. 完整的程序
#include <stdlib.h> #include <stdio.h> typedef int item; typedef struct Node //cau truc 1 Node { item Data; //du lieu cua Node Node *Left; //Con tro trai Node *Right; //con tro phai }; typedef struct DList //cau truc Cua List { Node *Head; //con tro dau Node *Tail; //con tro cuoi }; void Init(DList &L); int Isempty (DList L); //kiem tra DS rong int Len (DList L); // Do dai danh sach Node *Make_Node (Node *P, item x); //tao 1 Node P chua thong tin la x void Insert_first (DList &L, item x); //Chen x vao vi tri dau tien trong danh sach void Insert_last (DList &L, item x); //Chen x vao vi tri dau tien trong danh sach void Insert_k (DList &L, item x, int k); //chen x vao vi tri k trong danh sach void Del_first (DList &L, item &x); //Xoa phan tu dau tien void Del_k (DList &L, item &x, int k); //Xoa Node k trong danh sach int Search (DList L, item x); //tim x trong danh sach void Del_x (DList &L, item x); //xoa phan tu x trong danh sach void Input (DList &L); //nhap danh sach void Output (DList L); //xuat danh sach void Init(DList &L) { L.Head = NULL; // Con tro dau tro den NULL L.Tail = NULL; // Con tro cuoi tro den NULL } int Isempty (DList L) //kiem tra DS rong { return (L.Head == NULL); } int Len (DList L) // Do dai danh sach { Node *PH = L.Head, *PT = L.Tail; //tao Node PH (con tro duyet tu dau DS) và PT (con tro duyet tu cuoi DS) de duyet danh sach L int i = 0; //bien dem if (PH != NULL) i = 1; while (PH != NULL) //trong khi P chua tro den NULL (cuoi danh sach thi lam) { if (PH == PT) break; PH = PH->Right; //cho PH tro den Node tiep theo i++; if (PH == PT) break; PT = PT->Left; //cho PT tro den Node truoc do i++; } return i; //tra lai so Node cua L } Node *Make_Node (item x) //tao 1 Node P chua thong tin la x { Node *P = (Node *) malloc (sizeof (Node)); //Cap phat vung nho cho P P->Data = x; //Ghi du lieu vao Data P->Left = NULL; P->Right = NULL; return P; } void Insert_first (DList &L, item x) //Chen x vao vi tri dau tien trong danh sach { Node *P; P = Make_Node(x); //tao 1 Node P if (Isempty(L)) //Neu danh sach rong { L.Head = P; L.Tail = P; } else { P->Right = L.Head; L.Head->Left = P; L.Head = P; } } //Chen vao cuoi danh sach cung tuong tu void Insert_last (DList &L, item x) //Chen x vao vi tri cuoi trong danh sach { Node *P; P = Make_Node(x); //tao 1 Node P if (Isempty(L)) //Neu danh sach rong { L.Head = P; L.Tail = P; } else { L.Tail->Right = P; //ket noi voi danh sach P->Left = L.Tail; //P tro ve Node truoc L.Tail = P; //luu lai vi tri cuoi } } void Insert_k (DList &L, item x, int k) //chen x vao vi tri k trong danh sach { Node *PH = L.Head, *PT, *R; int i=1, l = Len(L); if (k<1 || k> l+1) printf("Vi tri chen khong hop le !"); //kiem tra dieu kien else { R = Make_Node(x); //tao 1 Node P if (k == 1) Insert_first(L,x); //chen vao vi tri dau tien else if (k == l+1) Insert_last(L,x); //chen vao vi tri cuoi else //chen vao vi tri 1<k<l+1 { while (PH != NULL && i != k-1) //duyet den vi tri k-1 { i++; PH = PH->Right; } PT = PH->Right; //xac dinh vi tri k R->Right = PT; //(1) R->Left = PH; //(2) PH->Right = R; //(3) PT->Left = R; //(4) } } } void Del_first (DList &L, item &x) //Xoa phan tu dau tien { if (!Isempty(L)) { x = L.Head->Data; //lay gia tri ra neu can dung L.Head = L.Head->Right; //Cho L tro den Node thu 2 trong danh sach } } void Del_last (DList &L, item &x) //Xoa phan tu dau tien { if (!Isempty(L)) { x = L.Tail->Data; L.Tail = L.Tail->Left; L.Tail->Right = NULL; } } void Del_k (DList &L, item &x, int k) //Xoa Node k trong danh sach { Node *PH = L.Head, *PT; int i=1, l = Len(L); if (k<1 || k> l) printf("Vi tri xoa khong hop le !"); //kiem tra dieu kien else { if (k == 1) Del_first(L,x); //xoa vi tri dau tien else if (k == l) Del_last(L,x); //xoa vi tri cuoi else //xoa vi tri 1<k<l+1 { while (PH != NULL && i != k-1) //duyet den vi tri k-1 { i++; PH = PH->Right; } x = PH->Right->Data; PT = PH->Right->Right; //xac dinh vi tri k+1 PH->Right = PT; PT->Left = PH; } } } int Search (DList L, item x) //tim x trong danh sach { Node *P=L.Head; int i=1; while (P != NULL && P->Data != x) //duyet danh sach den khi tim thay hoac ket thuc danh sach { P = P->Right; i++; } if (P != NULL) return i; //tra ve vi tri tim thay else return 0; //khong tim thay } void Del_x (DList &L, item x) //xoa phan tu x trong danh sach { int l = Search(L,x); while (l) { Del_k (L,x,l); //trong khi van tim thay x thi van xoa l = Search(L,x); } } void Input (DList &L) //nhap danh sach { int i=0; item x; do { i++; printf ("Nhap phan tu thu %d : ",i); scanf("%d",&x); if (x != 0) Insert_k(L,x,Len(L)+1); } while(x != 0); //nhap 0 de ket thuc } void Output (DList L) //xuat danh sach { Node *P=L.Head; while (P != L.Tail->Right) { printf("%5d",P->Data); P = P->Right; } printf("\n"); } int main() { DList L; Init(L); Input(L); Output(L); int lua_chon; printf("Moi ban chon phep toan voi DS LKD:"); printf("\n1: Kiem tra DS rong"); printf("\n2: Do dai DS"); printf("\n3: Chen phan tu x vao vi tri k trong DS"); printf("\n4: Tim mot phan tu trong DS"); printf("\n5: Xoa phan tu tai vi tri k"); printf("\n6: XOa phan tu x trong DS"); printf("\n7: Thoat"); do { printf("\nBan chon: "); scanf("%d",&lua_chon); switch (lua_chon) { case 1: { if (Isempty(L)) printf("DS rong !"); else printf ("DS khong rong !"); break; } case 2: printf ("Do dai DS la: %d.",Len(L));break; case 3: { item x; int k; printf ("Nhap phan tu can chen vao DS: "); scanf("%d",&x); printf ("Nhap vi tri can chen: "); scanf ("%d",&k); Insert_k (L,x,k); printf ("DS sau khi chen:\n"); Output(L); break; } case 4: { item x; printf ("Moi ban nhap vao phan tu can tim: "); scanf("%d",&x); int k=Search(L,x); if (k) printf ("Tim thay %d trong DS tai vi tri thu: %d",x,k); else printf ("Khong tim thay %d trong danh sach !",x); break; } case 5: { int k; item x; printf ("Nhap vi tri can xoa: "); scanf ("%d",&k); Del_k (L,x,k); printf ("DS sau khi xoa:\n"); Output(L); break; } case 6: { item x; printf ("Nhap phan tu can xoa: "); scanf ("%d",&x); Del_x (L,x); printf ("DS sau khi xoa:\n"); Output(L); break; } case 7: break; } }while (lua_chon !=7); return 0; }
[RPS-包括交=”2703″ 简码=”假”]
我的映泉, 他在代码文件记录到屏幕如何?
我不明白什么是写入的文件如何.
我问了到底有多空间, 为什么一定要L.Tail = P; //保存结束位置的?
我曾评论说,. 命令来保存最后一个位置, 因为悬臂删除指针到底会不会指向哪里L.Tail, 我需要把它指向一个新的位置.
一个OI町ê海LA CON卓L.tail-> 右班派卓已经空了CON卓L.head-> 规定必须返回null左康元粪清孔,然后就变成了杂? 在A E凸轮
Ënham拉L.head-> 离开班派卓已经一空
是的,你
– 在项目# 8 (删除终端元素列表) 我觉得行号 8 一个必须为L.head->左= NULL.
– 在项目# 9 (在位置k删除元素) 我觉得他们应该切断要素之间的联系要删除列表(指向NULL或删除始终) .
– 因为我使用动态分配的,所以我想我应该有 1 删除项目.
是的,你. 在这个系列中,我不得不跳过内存释放. 谢谢你对此有何评论离线.
我问为什么while循环:
– 部分 7 当前 14.
– 部分 9 当前 13.
检查PH != NULL做先生? 谢谢.
检查不同的最近的已知空列表尚未, 而另一些空少, 这样,我们才T->右边是, 如果不是会后悔.
有用的网站. 非常感谢
谢谢, 分享给好友NHE.
他问我,因为他是在make_node函数原型声明被传递到节点* P, 但为什么叫它只有每项x的函数,以便先生 ?
它的功能是这样写的:
节点* Make_Node (X项)
因此,通过x是正确的.
是的, 他让我问论坛 ! 放在if语句(是空的(L)) 在 2 del_first功能是什么意思del_last先生 ?, 为什么不呢 != ,
! 平均负.
的isEmpty(L) 检查列表是空的. 然后 !的isEmpty(L) 是它的负.
下面是用C或C ++先生之星的e-C ++将其保存为.C的开发复制不运行先生代码,谢谢!
C代码语法C ++混合NHE. CPP文件扩展名,你都OK.
服务员, 没有谈论的内兄弟链接列表.
中小企业, 一个没有谈论它.
请问如果要用有属性的学生列表代替数列,如何应用?
我只是将输入和输出测试更改为结构的输入和输出,
从这个文件中导入和导出数据有什么区别还是像bt一样,我运行以获取文件中的数据,它给我一个错误。
照常做. 打印前 1 number now printf 多个数字或字符串.