带头节点链表的操作(链表的创建、删除、查找、逆转、打印等等)
2014-06-09 23:23
387 查看
#include<iostream> #include<cassert> using namespace std; class Node { public: int data; Node* next; }; typedef class Node List_Node; /*--------------------------------------------------------- 在链表的末端插入新的节点,创建链表:这里我建立的是带有头节点 的链表,头结点的数据域是null,指针域存储的是第一个节点的地址 -----------------------------------------------------------*/ List_Node *creat(int n) { List_Node *head;//头指针 List_Node *p1, *p2;//p1为移动指针,p2为不断新建的节点 int i; head = (List_Node*)malloc(sizeof(List_Node)); head->data = NULL;//将头节点的数据置为NULL p1 = head;//将头结点的首地址赋给p1 for (i = 0; i < n; i++) { cout << "第"<<i<<"个数据" << endl; p2 = (List_Node*)malloc(sizeof(List_Node)); cin >> p2->data;//输入节点的所存储的数据 p1->next = p2;//将插入的节点的地址赋给上一个节点的链接指针 p1 = p2;//把节点p2的地址赋给p1,相当于把p1指向的位置后移动一位 } p1->next = NULL;//将最后一个节点的链接指针置为null return head;// 返回这个链表的首地址 } /*------------ 打印整个链表 -------------*/ void print(List_Node *L) { List_Node *p; p = L->next; cout << "输出链表:"; while (p) { cout << p->data << ' '; p = p->next; } cout << endl; } /*-------------------- 删除指定的节点 ----------------------*/ void delete_node(List_Node *L, int x) { List_Node *p = L; List_Node *pre; while (p->next->data != x && p != NULL)//找到被删除节点的前一个节点 p = p->next; if (p) { pre = p->next->next; free(p->next); p->next= pre ; } } //找到倒数第K个节点,最后一个节点为倒数第一个 List_Node *finde_node(List_Node* pHead, int k) { assert(pHead != NULL); // 先获得链表的长度 int length = 0; List_Node* p = pHead; while (p != NULL) { length++; p = p->next; } assert(length >= k); p = pHead; // 在从头移动 length-k次就好了 for (int i = 0; i<length - k; i++) p = p->next; return p; } /*-------------------------------------------------------- 求单链表倒数第N个数:利用两指针遍历表,保持他们的距离为n,当 后面的指针为NULL时,输出前面指针所指向的数,即倒数第N个数。 ----------------------------------------------------------*/ int index_backn(List_Node *L, int n) { List_Node *fir, *sec; fir = L->next; sec = L->next; int i; //当i小于n的时候第二个指针移动n步,当i大于等于n时候两个指针一起移动。 for (i = 0; sec; i++) { if (n<=i) { fir = fir->next; sec = sec->next; } else { sec = sec->next; } } return fir->data; } /*------------------------------------------------------------------ 找到单链表的中间结点:也是利用两个指针,一个慢移动指针(一次走一步),一 个快移动指针(一次走两步),当快指针指向NULL时,则慢指针指向中间节点。 --------------------------------------------------------------------*/ int find_mid(List_Node *L) { List_Node*fir, *sec; fir = L->next; sec = L->next; while ((sec->next) && (sec->next->next)) { fir = fir->next; sec = sec->next->next; } return fir->data; } /*------------------------------------------------------------------------- 链表逆置:利用三个指针来实现的,三个连续指针依 次向前移动,每次反转前两个指针指向数之间的指针 更清楚的一点的解释:通过不断的移动三个指针,每次逆转链接指针的指向,移动到 最后整个链表的链接指向和原来的指向刚好相反,儿节点中数据保持不变,在输出链表 中根据链表的指向输出数据。 ---------------------------------------------------------------------------*/ void ReverseList(List_Node *L) { if (!L->next->next) ; else{ List_Node *p3 = L->next->next->next; List_Node *p2 = L->next->next; List_Node *p1 = L->next; L->next->next = NULL;//将第一个节点的(头结点并不是第一个节点)指针域置为空 //不断移动两个指针,每次把前两个指针的链接指向逆转 while (p3){ p2->next = p1; p1 = p2; p2 = p3; p3 = p3->next; } p2->next = p1;//移动到最后别忘记把最后一个节点与倒数第二个节点链接上 L->next = p2;//把头节点链接上最后一个节点 } } //递归的方法逆转链表 List_Node *digui_ReverseList(List_Node *L) { if ((L == NULL) || (L->next == NULL)) return L; List_Node *p1 = L->next; List_Node *p2 = L->next->next; L=digui_ReverseList(p2); p2->next = p1; p1->next = NULL; return L; } /*----------------------------------- 带头节点表的删除 -------------------------------------*/ List_Node *my_reverse(List_Node *head) { if (head == NULL || head->next == NULL) return head; List_Node *pre, *cur,*ne; pre = head->next; //将前面几个节点的地址依次保存在新定义的结构体指针 cur = pre->next; while (cur) { ne = cur->next; cur->next = pre; //直接将两个指针的指向反转 pre = cur; //将当前节点赋给pre,将三个指针在链表中的位子都往后移一位 cur = ne; } head->next->next = NULL; //将原来的第一个节点的指针域赋为空,作为尾节点 head->next = pre; //将原来的尾节点变成新链表的第一个节点 return head; } int main() { List_Node *mylist; mylist = creat(5); //print(mylist); //List_Node *p; //delete_node(mylist, 3); //print(mylist); //p=finde_node(mylist, 2); //cout << p->data << endl; //print(mylist); int i,j=0; i= index_backn(mylist, 2); j = find_mid(mylist); cout << i << '\n' << j << endl; mylist = my_reverse(mylist); //ReverseList(mylist); print(mylist); return 0; }
相关文章推荐
- 树的基本结构,以及利用链表实现树的各项操作(创建、添加/删除/打印树节点、销毁等等)
- C语言实现单链表(带头结点)的基本操作(创建,头插法,尾插法,删除结点,打印链表)
- C语言实现单链表(带头结点)的基本操作(创建,头插法,尾插法,删除结点,打印链表)
- C语言实现带头结点的链表的创建、查找、插入、删除操作
- 线性表的链式存储格式基本操作:创建链表、插入、删除、查找、求表长、打印链表
- java实现创建链表以及插入节点,查找结点,删除节点等操作
- 关于链表结构的基本操作 c 实现 (创建,插入删除,反转,合并链表,查找,是否有环,链表相交情况)
- 链表操作综合练习(创建、拆分、插入、删除、合并、打印、逆置)
- tinyxml使用:创建XML,遍历打印xml文件 select操作,获取单个节点值,删除节点操作,修改节点操作,增加节点操作
- 算法学习-数据结构之链表操作,创建,插入,删除,查找。
- 单向链表的相关操作总结:创建、删除、查找、排序、统计链表大小、链表的反转和遍历等
- 数据结构之链表操作,创建,插入,删除,查找。
- 链表的基础操作总结(链表创建,插入,删除,遍历等等)
- 链表操作:创建,插入,删除,查找等功能
- 单链表创建、测长度、打印、删除节点、插入节点、排序、逆置
- 单向链表的创建、查找、删除、打印
- 不带头结点的链表操作----插入删除打印
- 带头节点循环单链表的操作(创建,保序插入,指定插入,删除指定表元,删除相同元素,统计某元素表元个数)
- 单链表的建立、测长、打印、删除节点、插入节点、排序、逆转
- C语言各种链表操作(创建、打印、删除、插入、反转)