线性表--单链表
2015-10-15 11:05
330 查看
#define _CRT_SECURE_NO_DEPRECATE //#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1 #include<iostream> using namespace std; typedef struct Node { int data; Node *next; }Node; Node *headPointer;//头指针 int listLength;//链表长度 /*将头指针加入到参数列表中*/ /* 1.初始化链表,输入数据,数据小于0结束输入。*/ void initList1() { listLength = 0; headPointer = new Node;//头指针指向头节点 if (!headPointer) { cout << "头节点内存分配失败!\n"; exit(0); } headPointer->next = nullptr; Node *temp = headPointer;//头节点的地址赋给接下来使用的中间变量 cout << "请输入链表数据(小于0结束输入):\n"; while (1)//链表赋值 { Node *p = new Node; if (!p) { cout << "内存分配失败!\n"; exit(0); } cin >> p->data; if (p->data < 0) { delete p; cout << "链表完成!\n"; return; //结束 }//数据小于0不可用,需要释放内存 temp->next = p; temp = p; temp->next = nullptr;//相当于p->next=nullptr;赋值为空指针,是个好习惯 listLength++; } cout << endl; } /* 2.在链表的第i个位置之 前 插入数据e */ void insertBefore(int i, int e) { cout << "在链表第" << i << "个位置前插入数据" << e << endl; if (i<1 || i>listLength) { cout << "数据插入位置错误!\n"; return; } Node *p = headPointer; Node *temp = new Node;//申请新内存 if (!temp) { cout << "内存分配失败!\n"; exit(0); } while (--i) p = p->next;//找到第i-1个位置 temp->data = e; temp->next = p->next; p->next = temp; listLength++; cout << "链表长度为:" << listLength << " 数据插入成功!\n"; } /*在链表第i个位置之 后 插入数据e*/ void insertAfter(int i, int e) { cout << "在链表第" << i << "个位置之后插入数据" << e << endl; if (i<1 || i>listLength) { cout << "数据插入位置错误!\n"; exit(0); } Node *p = headPointer; Node *temp = new Node;//申请新内存 if (!temp) { cout << "内存分配失败!\n"; exit(0); } while (i--) p = p->next; temp->data = e; temp->next = p->next; p->next = temp; listLength++; cout << "链表长度为:" << listLength << " 数据插入成功!\n"; } /* 4. 删除链表的第i个位置的数据 */ bool deleteList(int i) { cout << "删除链表第" << i << "个位置的数据\n"; Node *p = headPointer; while (--i) p = p->next;//找到第i-1个位置 Node *deleteTemp = p->next;//为第i个位置的内存释放做准备 p->next = p->next->next; delete deleteTemp; listLength--; cout << "链表长度为:" << listLength << " 数据删除成功!\n"; return true; } /* 5.打印链表所有数据 */ bool printList() { if (headPointer->next == nullptr) { cout << "链表为空!\n"; return false; } cout << "链表长度为:" << listLength << "打印链表:\n"; Node *p = headPointer; while (p->next != nullptr) { cout << p->next->data << " "; p = p->next; } cout << "链表打印成功!\n\n"; return true; } /* 6. 清除链表*/ bool clearList() { if (headPointer->next == nullptr) { cout << "链表为空,无法再清除!\n"; return false; } Node *p = headPointer; Node *temp; while (p != nullptr) { temp = p->next; delete p; p = temp; listLength--; } cout << "链表清除成功!\n" << "链表长度为" << listLength + 1 << endl;//头节点不计入链表长度,而清除链表时,头节点也被清除 return true; } /* 7.返回链表中第i个结点中的数据的地址*/ int* getData(int i) { if (i<1 || i>listLength) { cout << i << "值超出链表范围!\n"; return false; } Node *p = headPointer; while (i--) p = p->next; return &(p->data); } /* 8. 给定数值,判断链表中是否存在该数值,如果存在返回数值相同的第一个结点的地址*/ Node* findList(int e) { Node *p = headPointer; while (p->next != nullptr) { p = p->next; if (p->data == e) return p; } return nullptr; } /* 9. 修改链表中第i个结点的数据*/ bool modifyList(int i, int e) { if (i<1 || i>listLength) { cout << "修改的结点位置错误!\n"; return false; } Node *p = headPointer; while (i--) p = p->next; p->data = e; return true; } /* 10. 逆位序输入n个元素的值*/ void initList2(int n) { headPointer = new Node;//头指针指向头节点 headPointer->next = nullptr; while (n--) { Node *p = new Node; if (!p) { cout << "内存分配失败!\n"; exit(0); } cin >> p->data; p->next = headPointer->next; headPointer->next = p; } } /* 11. 按顺序归并两个链表*/ bool mergeList(Node* &a, Node* &b, Node* &c) { Node *pa = a->next; Node *pb = b->next; Node *pc = c = a;//把a的头节点给c,最后要删除b的头节点 while (pa&&pb) { if (pa->data <= pb->data) { pc->next = pa; pc = pa; pa = pa->next; } else { pc->next = pb; pc = pb; pb = pb->next; } } pc->next = pa ? pa : pb; delete b; return true; } /*12.交换两个节点的data*/ void swapList(Node *i,Node *j) { int temp = i->data; i->data = j->data; j->data = temp; } /* 13. 链表排序*/ //pStart指向首个元素的节点,不是头节点;pEnd是null,也就是最后一个节点的next void sortList(Node *pStart,Node *pEnd) { if (pStart == pEnd||pStart->next==pEnd) return; //这里的第一个节点不是头节点,而是头节点的下一个节点,依次类推 int dataBase = pStart->data; Node *firstNode = pStart;//保存第一个节点(也就是头节点的下一个节点) Node *i = pStart; Node *j = pStart->next;//指向第二个节点 while (j != pEnd) { if (j->data < dataBase) { i = i->next; swapList(i, j); } j = j->next; } swapList(firstNode, i); sortList(pStart, i); sortList(i->next, pEnd); } /*14.已知线性表数据递增有序,删除表中所有值大于mink且小于maxk的数据,并释放被删除的结点*/ bool deleteYouWant1(int mink, int maxk) { Node *p = headPointer; while (p->next != nullptr)//先判断 { if (p->next->data>mink)//先找到满足条件的点然后删除,而不是指针已指向满足条件的点才去删除 { if (p->next->data >= maxk) return true; Node *willDelete = p->next; p->next = p->next->next; delete willDelete; listLength--; } else p = p->next; } return false; } /*15.已知线性表数据递增无序,删除表中所有值大于mink且小于maxk的数据,并释放被删除的结点*/ void deleteYouWant2(int mink, int maxk) { Node *p = headPointer; while (p->next != nullptr) // p->next != nullptr 先判断,而不是 p!= nullptr,因为你下面是提前判断数据data,如果 //不提前判断是不是nullptr,下面的数据判断可能造成非法访问data的错误 { if (p->next->data > mink && p->next->data < maxk) { Node *willDelete = p->next; p->next = p->next->next; delete willDelete; listLength--; } else p = p->next; } } /*16.删除数据相同的节点,仅只保留一个*/ void uniqueList1() { Node *p = headPointer->next; while (p != nullptr) { Node *temp = p->next; Node *frontNode = p;//保留我要删除的节点的上一个节点,以便删除节点时,将前后两个节点相接 while (temp!=nullptr) { if (temp->data == p->data) { Node *willDelete = temp; frontNode->next = temp->next; temp = temp->next; delete willDelete; listLength--; } else { frontNode = temp; temp = temp->next; } } p = p -> next; } } /*17.删除数据相同的节点,仅只保留一个*/ void uniqueList2()//和上面的版本不一样之处就是,没有frontNode指针保留前一个结点,而是采用先判断再去删除的办法 { Node *p = headPointer; while (p != nullptr) { Node *temp = p; while (temp->next != nullptr)//temp->next != nullptr采用先判断再去删除的办法,而不是temp!=nullptr //进行删除操作时,我们是肯定是要知道删除节点的上一个节点,要不我们每走一步,保留上一个节点, //要不在删除节点的前面停下来uniqueList2采用的是后者 { if (temp->next->data == p->data) { Node *willDelete = temp->next; temp->next = temp->next->next; delete willDelete; listLength--; } else temp = temp->next; } p = p->next; } } int main() { return 0; }
相关文章推荐
- 跟我学SpringMVC目录汇总贴、PDF下载、源码下载
- 常用Linux维护tomcat文件命令
- Pthread创建线程后必须使用join或detach释放线程资源
- html.parser无法完全解析网页之BUG的修正
- DataTable 设置primarykey 后进行 Merge操作
- eclipse+ADT使用第三方静态库及COCOS2d问题汇总
- win10驱动
- jQWidgets v3.9.0正式发布[附下载]
- 第一章 Web MVC简介 —— 跟开涛学SpringMVC
- Ugui的介绍视频地址和笔记
- Unix学习笔记-----管道的本质是什么???
- 利用基本数据类型的包装类中的方法实现类型转换
- maven 打包 negative time 异常的问题
- Javascript中call的使用
- sqlserver不能直接create table as select
- 从0开始学java——JUnit4 复习,其实基本思想还是那些,不过采用了新的注释格式的语法
- [Flex] ButtonBar系列——flex3 ButtonBar圆角菜单的运用
- .NET Framework中Object基类有哪些方法?
- copy_to_user,copy_from_user,get_user,put_user函数比较
- DecimalFormat 用法