赞
踩
目录
位置:PPT第二章:127
默认前置:
- #include<iostream>
- using namespace std;
- #include<stdlib.h>//存放exit
- #include<math.h>//OVERFLOW,exit
-
- #define MAXlength 100 //初始大小为100,可按需修改
-
- typedef int Status; //函数调用状态
-
- struct K
- {
- float a;
- int b;
- string c;
- };
- typedef K Elemtype; //函数调用状态
-
- struct Lnode
- //node:结; 结点;
- {
- Elemtype data;
- Lnode* next;
- };
- typedef Lnode* LinkList;
project 1:(自己写的,凑合着也能用)
- Status 取第i个元素(LinkList L, int i,Elemtype e)
- {
- if (链表是否为空(L))
- cerr << "链表为空" << endl;
- if (i < 1)
- cerr << "i不对" << endl;
- LinkList p = L->next;
- int j = 0;
- while (p)
- {
- if (i == j)
- {
- e = p->data;
- break;
- }
- p = p->next;
- j++;
- }
- return true;
- }
project 2:根据课程上写的(算法复杂度低一些,比较好用)
- Status GetElem“i”(LinkList L, int i, Elemtype e)
- {
- LinkList p;
- p = L->next;
- int j = 1;
- while (p && i > j)
- {
- p = p->next;
- j++;
- }
- if (i<0 || i<j || !p)
- return false;
- e=p->data;
- return true;
- }
project 1:
- Status 按值查找地址和位置序号(LinkList L,Elemtype e)
- {
- LinkList p; int i=1;
- p = L->next;
- while (p)
- {
- i++;
- if (e == p->data)
- {
- cout << "地址为: " << p << ";" << endl;
- cout << "位置序号为: " << i <<";" << endl;
- }
- p = p->next;
- }
- //如果最后运行失败查找不到最后怎么返回ERROR?
- if (p = NULL)
- return NULL;
- return true;
- }
但是要注意,如果要这么写的话,在类型K的声明里,还需要加上手撸判断表达式的定义:
- struct K
- {
- float a;
- int b;
- string c;
- bool operator==(K& t)
- {
- return t.a == a && t.b == b;
- //&& t.c = c;
- }
- };
- typedef K Elemtype; //函数调用状态
project 2:根据课程上写的(算法复杂度低一些,比较好用)
- Status LocateELem(LinkList L, Elemtype e)
- {
- //在线性表L中查找值为e的数据元素
- //找到,则返回L中值为e的数据元素的地址,查找失败返回NULL
- auto p = L->next; int i=1;
- while (p && p->data != e)
- {
- i++;
- if (e == p->data)
- {
- cout << "地址为: " << p << ";" << endl;
- cout << "位置序号为: " << i << ";" << endl;
- }
- p = p->next;
- }
- if (p == NULL)
- return NULL;
- return true;
- }
同理:
- struct K
- {
- float a;
- int b;
- string c;
- bool operator==(K& t)
- {
- return t.a == a && t.b == b;
- //&& t.c = c;
- }
- bool operator!=(K& t)
- {
- return t.a != a || t.b != b;
- //|| t.c = c;
- }
- };
- typedef K Elemtype; //函数调用状态
project 1:
- Status 插入(LinkList L,int i,Elemtype e)
- {
- LinkList p,s; int j = 1;
- p = L->next;
- s->data = e;
- while (p)//&& j < i)
- {
- if (j == i-1)
- {
- s->next = p->next;
- p->next = s;
- return true;
- }
- p = p->next;
- j++;
- }
- if (!p || j > i - 1)
- return false;//别忘了写插入非法时的情况
- }
project 2:根据课程上写的
- Status Listlnsert(LinkList& L, int i, Elemtype e)
- {
- auto p = L; int j = 0;
- while (p && j < i - 1)
- { p = p->next; ++j; }
- if (!p ||j > i - 1)
- return false;
- auto s = new Lnode;
- s->data = e;
- s->next=p->next;
- p->next = s;
- return true;
- }//Listlnsert_L
问题:(其实我觉得应该是一样的,只是把这个还没有确定的问题暂时先放在这里mark一下希望来日可以顺利解答)在这个算法里:
int j = 1;p = L->next;
auto p = L; int j = 0;
等价吗
project 1:
- Status 删除(LinkList& L, int i)
- {
- LinkList p,s,q; int j=1;
- while (p&&j<i-1)
- {
- p->next;
- j++;
- }
- s = p->next;
- q = s->next;
- delete s;
- p = q;
- return true;
- }
project 2:
- Status 删除(LinkList& L, int i)
- {
- LinkList p, s; int j = 1;
- while (p && j < i - 1)
- {
- p->next;
- j++;
- }
- s = (p->next)->next;
- delete p->next;
- p->next = s;
- return true;
- }
project 3:根据视频(逻辑更严谨)
- Status 删除(LinkList& L, int i)
- {
- LinkList p = L, s; int j = 1;
- while (p && j < i - 1)
- {
- p = p->next;
- j++;
- }
- if (!p || j > i - 1)
- return false;
- s = p->next;
- p->next = s->next;
- //auto e = s->data;
- delete s;
- return true;
- }
各操作的时间复杂度:
单链表的查找、插入和删除:O(n)
线性表的插入和删除:O(1)
project 1:
用头插法建立链表,并插入(输入)数据结点(这里简化我们只输入3个)a,b,c
- Status 头插法(LinkList &L)
- {
- //创建空链表
- K a, b, c;
- L= new Lnode;//就一个首元结点
- L->next = NULL;
- //L->data里面没什么东西
- //(我们也不知道里面有啥)
- //但可以确定,里面不为空(NULL)
-
- auto p = new Lnode;//(头)插入
- L->data = c;
- p->next = L->next;
- L->next = p;
- //每次循环的操作,唯一的区别只有:
- //data域输入的数值不同
- auto p = new Lnode;
- L->data = b;
- p->next = L->next;
- L->next = p;
- //
- auto p = new Lnode;
- L->data = a;
- p->next = L->next;
-
- }
实际上,这个程序是错的,程序设计逻辑:
Points:
关于
L= new Lnode;
实际上我觉得真的是多此一举:
系统开始带有参数LinkList &L的时候不是实际上已经提前给你默认提前分配好了L的内存空间吗,你他*还在这边费劲干啥呢
另外, L= new Lnode;这种开辟空间的格式是哪弄出来的???
原来学过关于new的用法,只有通过定义指针分配新空间,like:
Lnode* p = new Lnode;
但是既然这里可行可用,那我们也需要记住:
L= new Lnode;
即:
<开辟空间首地址> = new <开辟空间存放数据类型>
格式(前面没有定义过记得加auto)
最后经过我们后面深入专门去学习了关于new的使用方法和格式,发现并不是这么一回事:
并不是因为代表L是表,而像我们猜测的那样有了什么新的格式
而是由于表头前面的Linklist &L,表明了他本来就是一个指针,依然属于符合原来的使用规范
也就是说,如果前面(形参传递时)我们已经定义过了该变量,那么在后面开辟空间时
我们就不用(也不能)再(重新)申明变量的类型
详见:
数据结构与算法基础(王卓)(8)附:关于new的使用方法详解_宇 -Yu的博客-CSDN博客_数据结构new
C语言日记 26 指针与函数,动态存储分配_宇 -Yu的博客-CSDN博客
末尾
OK,现在,我们来修正project 1:
注意如果我们想要实现像前面画的图中的“我们想要达到的效果”,那是不可能的了
我们最多只能退而求其次:
让头指针指向头结点,搞一个新的首元结点插进去,而不是搞个新的首元结点(办不到)
project 2:
其实要实现对前面的修正和更改也很简单,只需:
把语句 L->data = (结点信息);修改为:p->data = (结点信息),即可;
- Status 头插法(LinkList& L)
- {
- //创建空链表
- K a, b, c;
- L = new Lnode;//就一个首元结点
- L->next = NULL;//别忘了这句
- //L->data里面没什么东西
- //(我们也不知道里面有啥)
- //但可以确定,里面不为空(NULL)
-
- auto p = new Lnode;//(头)插入
- p->data = c;
- p->next = L->next;
- L->next = p;
- //
- auto p = new Lnode;
- p->data = b;
- p->next = L->next;
- L->next = p;
- //
- auto p = new Lnode;
- p->data = a;
- p->next = L->next;
- }
正式根据PPT(148)设计的程序流程来设计实现程序:
Project 3:
- Status 头插法()//LinkList &L)
- {
- //创建空链表
- auto L = new Lnode;
- //创建新节点
- auto p = new Lnode;
- K an,an_1;
- p->data = an;
- //把新节点和链表串起来
- p->next = L->next;
- L->next = p;
- //重复下一轮循环
- auto p = new Lnode;
- p->next = L->next;
- L->next = p;
- }
将其实现为我们具体能够落地实现使用的函数:(假设我们输入n个节点的数据)
- Status 头插法(LinkList& L, int n)
- {
- //创建空链表
- auto L = new Lnode;
- L->next = NULL;//别忘了这句
- int i = 1;
- while (i <= n)
- {
- auto p = new Lnode;
- cin >> p->data.a;
- cin >> p->data.b;
- cin >> p->data.c;
- p->next = L->next;
- L->next = p;
- i++;
- }
- return true;
- }
这个结果基本和标准答案差不多,只不过标准答案用的是for语句:
- void CreatListHead(LinkList& L, int n)
- {
- auto L = new Lnode;
- L->next = NULL;//别忘了这句
- for (int i = n; i > 0; --i)
- //for (int i = 0; i < n; ++i)
- {
- auto p = new Lnode;
- cin >> p->data.a;
- cin >> p->data.b;
- cin >> p->data.c;
- p->next = L->next;
- L->next = p;
- i++;
- }
- }
最终使用时,不能使返回表和构造表重定义:
- Status 头插法(LinkList& A, int n)
- {
- //创建空链表
- auto L = new Lnode;
- L->next = NULL;//别忘了这句
- int i = 1;
- while (i <= n)
- {
- auto p = new Lnode;
- cin >> p->data.a;
- cin >> p->data.b;
- cin >> p->data.c;
- p->next = L->next;
- L->next = p;
- i++;
- }
- A = L;
- return true;
- }
时间复杂度:O(n)
project 1:
- Status 尾插法(int n)
- {
- auto L = new Lnode;
- L->next = NULL;
- LinkList r = L;
- for (auto i = 1; i <= n; i++)
- {
- auto p = new Lnode;
- cin >> p->data.a;
- cin >> p->data.b;
- cin >> p->data.c;
- p->next = NULL;
- r->next = p;//尾插
- r = p;
- }
- return true;
- }
project 2:(同理,不再赘述)
- Status 尾插法(LinkList& A, int n)
- {
- auto L = new Lnode;
- L->next = NULL;
- LinkList r = L;
- for (auto i = 1; i <= n; i++)
- {
- auto p = new Lnode;
- cin >> p->data.a;
- cin >> p->data.b;
- cin >> p->data.c;
- p->next = NULL;
- r->next = p;//尾插
- r = p;
- }
- A = L;
- return true;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。