3.指针和数据结构
学习编程的菜鸟通常有一个不正确的姿势:回避指针。
但是:指针是几乎所有算法表达的基础(上图)
实际上指针在效率上有优势;
实际上指针是实现大部分数据结构的必要工具;
数据结构是解决复杂算法问题的基础。
1) 指针和链表:
顺序表的特点为:逻辑相邻的两节点其物理地址也是相邻的;链表的特点为:逻辑相邻的两节点其物理地址不相邻。顺序表的存储方式是:节点元素连续存放在存储单元;链表的存储方式是:节点元素随机存放在存储单元。
对比顺序表(如数组)和链表:
设计一个典型链表对象,主要实现函数如下:
InitList(LinkList &L) 参数:单链表L 功能:初始化 时间复杂度 O(1)
ListLength(LinkList L) 参数:单链表L 功能:获得单链表长度 时间复杂度O(n)
ListInsert(LinkList &L,int i,ElemType e) 参数:单链表L,位置i,元素e 功能:位置i后插 时间复杂度O(n);若已知指针p指向的后插 O(1)
ListDelete(LinkList &L,int i) 参数:单链表L,位置i 功能:删除位置i元素 时间复杂度O(n);若已知p指针指向的删除 最好是O(1),因为可以与后继结点交换数据域,然后删除后继结点。最坏是O(n),即从头查找p之前的结点,然后删除p所指结点。
LocateElem(LinkList L,ElemType e) 参数:单链表L,元素e 功能:查找第一个等于e的元素,返回指针 时间复杂度O(n)
代码如下:
#include
#include
#include
#include
#include
using namespace std;
#define Status int
#define ElemType int
//单链表结点数据结构
typedef struct LNode
{
ElemType data;//数据域
struct LNode *next;//指针域
}LNode,LinkList;
//基本操作函数//
//初始化函数(本例链表至少一个头结点,头结点无数据)
Status InitList(LinkList &L)
{
L = new LNode;//生成头结点 这样删除等操作就不必分第一个结点和其他了
L->next = NULL;
return 1;
}
//获取单链表长度 (头结点无数据,不算)
int ListLength(LinkList L) //传进来的是头结点地址
{
LinkList p=L;int sum=0;
while§
{
sum++;
p=p->next;
}
return sum-1;//去除头结点
}
//插入函数–后插法 插入到第i(1<=i<=length+1)个位置 即i-1之后 不必区分i的位置
bool ListInsert(LinkList &L,int i,ElemType e)
{
LNode* s;LinkList p=L;int j=0;//j=0是头结点
while(p&&(j<i-1))//j指到i-1位置
{
p=p->next;
++j;
}
if(!p||j>i-1)//i<1或者i>ListLength(L)+1时,插入位置无效 不调用ListLength,提高效率
{
printf(“插入位置无效!!!\n”);
return false;
}
s=new LNode;
s->data=e;
s->next=p->next;
p->next=s;
return true;
}
//删除函数 删除位置i的结点 即删除i-1之后的结点
bool ListDelete(LinkList &L,int i)
{
LNode* s;LinkList p=L;int j=0;
LinkList q;
while(p&&(j<i-1))//j指到i-1位置
{
p=p->next;
++j;
}
if(!(p->next)||j>i-1)//i<1或者i>ListLength(L)时,删除位置无效
{
printf(“删除位置无效!!!\n”);
return false;
}
q=p->next;
p->next=q->next;
free(q);//释放空间
return true;
}
//查找函数 按值查找 查找第一个等于e的结点 成功返回该结点指针,否则返回NULL
LNode LocateElem(LinkList L,ElemType e)
{
LNode p=L;
while(p&&(p->data!=e))
{
p=p->next;
}
return p;
}
//功能实现函数(略)//
//遍历输出函数
void PrintList(LinkList L)
{
LinkList p=L->next;//跳过头结点
if(ListLength(L))
{
printf(“当前单链表所有元素:”);
while§
{
printf("%d “,p->data);
p=p->next;
}
printf(”\n");<