线性表篇
来源:互联网 发布:s25fl256s 单片机 编辑:程序博客网 时间:2024/06/14 04:22
<<------表示方法------>>
1. 线性表之顺序表示
方法一:动态分配
#define LIST_INIT_SIZE 100 //线性表存储空间的初始分配量
#define LISTINCREMENT 10 //线性表存储空间的分配增量
typedef struct
{
ElemType *elem; //存储空间基址
int lenght; //当前长度,即元素个数
int listsize; //当前分配的存储容量
}SqList;
方法二:静态分配
#define MaxSize 50
typedef struct
{
ElemType data[MaxSize]; //存放顺序表元素
int length; //存放顺序表长度
}SqList;
2. 线性表之链式表示
typedef struct LNode
{
ElemType data;
struct LNode *next;
}LNode, *LinkList;
3. 线性表之双向链表
typedef struct DuLNode
{
ElemType data;
struct DuLNode *prior;
struct DuLNode *next;
}DuLNode, *DuLinkList;
<<------常见算法------>>
1. 设计一个高效算法,将顺序表的所有元素逆置,要求算法空间复杂度为O(1).
解:扫描顺序表L的前半部分元素,对于元素L.data[i](0<=i<L.length/2),将其与后半部分对应元素L.data[L.length-i-1]进行交换。算法如下:
void reverse(SqList &L)
{
int i;
ElemType x; //O(1)
for(i=0; i<L.length/2; i++)
{
x = L.data[i];
L.data[i] = L.data[L.length-i-1];
L.data[L.length-i-1] = x;
}
}
2. 设计一个高效算法,从顺序表中删除所有元素值为x的元素,要求空间复杂度为O(1).
解:首先确定顺序表L中第一个值为x的元素的位置i,然后依次检查L.data[i+1]~L.data[L.length-1]中每一个元素L.data[j](i+1<=j<L.length),若L.data[j]!=x,则将L.data[j]存入L.data[i]中,并令i增1。最后顺序表长为i。算法如下:
void delall(SqList &L, ElemType x)
{
int i=0, j;
while(i<L.length && L.data[i] != x) //查找第一个为x的元素
i++;
for(j=i+1; j<L.length; j++)
if(L.data[j] != x)
{
L.data[i] = L.data[j];
i++;
}
L.length = i;
}
3. 设计一个顺序表L,其元素为整形数据,设计一个算法将L中所有小于0的整数放在前半部分,大于等于0的整数放在后半部分。
解:从L的两端查找,前端大于等于0的元素(位置i),后端找小于0的元素(位置j),然后交换两位置的元素。算法如下:
void move(SqList &L)
{
ElemType temp;
int i=0,j=L.length-1;
while(i<j)
{
while(i<j && L.data[i]<0)
i++; //从前向后找大于等于的元素L.data[i]
while(i<j && L.data[j]>=0)
j--; //从后向前找小于的元素L.data[j]
if(i < j) //交换L.data[i]和L.data[j]
{
temp = L.data[i];
L.data[i] = L.data[j];
L.data[j] = temp;
}
}
}
4. 设计一个算法从顺序表中删除重复的元素,并使剩余元素间的相对次序保持不变。
解:假设L.data[0]~L.data[j]中没有重复的元素。检测L.data[i](j<i<L.length),若L.data[i]和L.data[0]~L.data[j]中任何一个元素都不相同,则将L.data[i]存入L.data[j+1]。算法如下:
void delsame(SqList &L)
{
int i, j, k;
if(L.length > 0)
{
j = 0;
for(i=1; i<L.length; i++)
{
k = 0;
while(k<=j && L.data[k] != L.data[i])
k++;
if(k > j)
{
j++;
L.data[j] = L.data[i];
}
}
L.length = j+1;
}
}
5. 有序顺序表的归并算法
解:void Merge(SqList L1, SqList L2, SqList L3)
{
int i=0, j=0, k=0; //i扫描L1,j扫描L2
while(i<L1.length && j<L2.length)
{
if(L1.data[i] < L2.data[j])
{
L3.data[k] = L1.data[i];
i++; k++;
}
else if(L1.data[i] > L2.data[j])
{
L3.data[k] = L2.data[j];
j++; k++;
}
else //L1.date[i] == L2.data[j]
{
L3.data[k] = L1.data[i];
i++; j++; k++;
}
}
while(i<L1.lenght) //若L1未扫描完,将余下的元素归并至L3中
{
L3.data[k] = L1.data[i];
i++; k++;
}
while(j<L1.lenght) //若L2未扫描完,将余下的元素归并至L3中
{
L3.data[k] = L2.dataj];
j++; k++;
}
L3.length = k;
}
6. 有序单链表的归并算法
解:void Merge(LinkList La, LinkList Lb, LinkList Lc)
{
LinkList pa = La->next, pb = Lb->next, pc; //pa扫描L1,pb扫描L2
Lc = pc = La; //使Lc的头结点指向La头结点,pc指向Lc尾节点
while(pa != NULL && pb != NULL)
{
if(pa->data < pb->data)
{
pc->next = pa;
pc = pa;
pa = pa->next;
}
else if(pa->data > pb->data)
{
pc->nex = pb;
pc = pb;
pb = pb->next;
}
else // pa->data == pb->data
{
pc->next = pa;
pc = pa;
pa = pa->next;
pb = pb->next;
}
}
pc->next = pa ? pa : pb; //将为扫描完的节点接入pc
pc->next = NULL;
}
7. 有一个线性表,采用带头结点的单链表L存储,设计一个算法将其就地逆置。所谓就地就是指辅助空间为O(1).
解:用p指针扫描原单链表,先将头结点L的next设为NULL而变成一个空链表,然后将凭借点采用头插法插入到L中。算法如下:
void Reverse(LinkList &L)
{
LinkList p = L->next, q;
L->next = NULL;
while(p != NULL)
{
q = p->next;
p->next = L->next; //将p节点插入到新链表的前面
L->next = p;
p = q;
}
}
- 线性表篇
- 线性表--线性存储
- 线性表 线性结构
- 《数据结构之线性篇》-线性表的C++实现
- 数据结构复习篇:线性表
- 数据结构复习篇:线性表
- 数据结构之【线性表】篇
- 线性表
- 线性表
- 线性表
- 线性表
- 线性表
- 线性表
- 线性表
- 线性表
- 线性表
- 线性表
- 线性表
- 无奈
- 解读IT认证“敲门砖”
- A Mainframe IDE Powered By Unix Technology [12] - Integrate submit JCL and compile with Vim
- 刚装Fedora 13,得小技巧两则
- 写在Scrum开始之前
- 线性表篇
- XML解析技术
- H-JETAG + Keil uVsion4调试ARM
- symbian对话框汇总3
- Eclipse插件的安装方法三则
- symbian对话框汇总2
- CPLD 八段数码管时钟显示的VHDL实现
- php 中的判断 总结
- 9款免费的Windows远程协助软件