线性表(逻辑结构)
1.线性表是最简单、最基本、最常用的数据结构。线性表是线性结构的抽象(Abstract),线性结构的特点是结构中的数据元素之间存在一对一的线性关系。这种一对一的关系指的是数据元素之间的位置关系,即:(1)除第一个位置的数据元素外,其它数据元素位置的前面都只有一个数据元素;(2)除最后一个位置的数据元素外,其它数据元素位置的后面都只有一个元素。也就是说,数据元素是一个接一个的排列。因此,可以把线性表想象为一种数据元素序列的数据结构。
1.1顺序表:在计算机内保存线性表最简单、最自然的方式,就是把表中的元素一个接一个地放进顺序的存储单元,这就是线性表的顺序存储(Sequence Storage)。线性表的顺序存储是指在内存中用一块地址连续的空间依次存放线性表的数据元素,用这种方式存储的线性表叫顺序表(Sequence List),如图2.1所示。顺序表的特点是表中相邻的数据元素在内存中存储位置也相邻。只要知道顺序表的基地址和每个数据元素所占的存储单元的个数就可以求出顺序表中任何一个数据元素的存储地址。并且,由于计算顺序表中每个数据元素存储地址的时间相同,所以顺序表具有和数组一样随机存取的特点。
其他的不多做介绍了,无非就是一些增加删除,查询等操作,因为是连续存储的关系都是简单的移位操作,现在做一道简单的练习题
question:有数据类型为整型的顺序表La和Lb,其数据元素均按从小到大的升序排列,编写一个算法将它们合并成一个表Lc,要求Lc中数据元素也按升序排列.
myanswer:
代码
using
System;
using
System.Collections.Generic;
using
System.Text;
namespace
ConsoleApplication2
{
public
class
SeqList
<
T
>
{
private
int
maxsize;
private
int
last;
private
T[] data;
//
构造器
public
SeqList(
int
size)
{
data
=
new
T[size];
maxsize
=
size;
last
=
-
1
;
}
public
T
this
[
int
index]
{
get
{
return
data[index];
}
set
{
data[index]
=
value;
}
}
public
int
GetLength()
{
return
last
+
1
;
}
public
void
Append(T item)
{
data[last
+
1
]
=
item;
last
++
;
}
public
void
ReversSeqList()
{
T tmp;
int
len
=
last;
for
(
int
i
=
0
; i
<=
last
/
2
;
++
i)
{
tmp
=
data[i];
data[i]
=
data[len
-
i];
data[len
-
i]
=
tmp;
}
}
public
void
Printf()
{
for
(
int
i
=
0
; i
<=
last; i
++
)
{
Console.Write(data[i]);
}
Console.ReadLine();
}
}
public
class
Program
{
static
void
Main(
string
[] args)
{
SeqList
<
int
>
a
=
new
SeqList
<
int
>
(
3
);
a.Append(
1
);
a.Append(
3
);
a.Append(
5
);
SeqList
<
int
>
b
=
new
SeqList
<
int
>
(
2
);
b.Append(
2
);
b.Append(
4
);
Merge(a, b);
}
public
static
void
Merge(SeqList
<
int
>
La, SeqList
<
int
>
Lb)
{
int
len
=
La.GetLength()
+
Lb.GetLength();
SeqList
<
int
>
lc
=
new
SeqList
<
int
>
(len);
int
indexLa
=
0
;
int
indexLb
=
0
;
while
(indexLa
<
La.GetLength()
||
indexLb
<
Lb.GetLength())
{
//
全部未超出界限
if
(indexLa
<
La.GetLength()
&&
indexLb
<
Lb.GetLength())
{
if
(La[indexLa]
<
Lb[indexLb])
{
lc.Append(La[indexLa]);
indexLa
++
;
}
else
{
lc.Append(Lb[indexLb]);
indexLb
++
;
}
}
//
lb超出界限
else
{
if
(indexLa
<
La.GetLength()
&&
indexLb
==
Lb.GetLength())
{
lc.Append(La[indexLa]);
indexLa
++
;
}
else
{
lc.Append(Lb[indexLb]);
indexLb
++
;
}
}
}
lc.Printf();
}
}
}
其实很简答就是一个对利用数组,采用泛型的一个通用实现
1.2 单链表顺序表是用地址连续的存储单元顺序存储线性表中的各个数据元素,逻辑上相邻的数据元素在物理位置上也相邻。因此,在顺序表中查找任何一个位置上的数据元素非常方便,这是顺序存储的优点。但是,在对顺序表进行插入和删除时,需要通过移动数据元素来实现,影响了运行效率。本节介绍线性表的另外一种存储结构——链式存储(Linked Storage),这样的线性表叫链表(Linked List)。链表不要求逻辑上相邻的数据元素在物理存储位置上也相邻,因此,在对链表进行插入和删除时不需要移动数据元素,但同时也失去了顺序表可随机存储的优点。
因为链表使用任意一组存储单元来存储数据,那么怎么表示两个数据逻辑上的相邻关系,为此在存储数据信息时,除了存储本身的信息外,还需要存储它相邻数据的信息。这两部分信息组成该数据元素的存储映像(Image),称为结点(Node)。把存储据元素本身信息的域叫结点的数据域(Data Domain),把存储与它相邻的数据元素的存储地址信息的域叫结点的引用域(Reference Domain)。因此,线性表通过每个结点的引用域形成了一根“链条”,这就是“链表”名称的由来。 如果结点的引用域只存储该结点直接后继结点的存储地址,则该链表叫单链表(Singly Linked List)。把该引用域叫next。因为比顺序表复杂所以在这给出详细的实现
结点:
代码
public
class
Node
<
T
>
{
private
T data;
//
数据域
private
Node
<
T
>
next;
//
引用域
//
构造器
public
Node(T val, Node
<
T
>
p)
{
data
=
val;
next
=
p;
}
//
构造器
public
Node(Node
<
T
>
p)
{
next
=
p;
}
//
构造器
public
Node(T val)
{
data
=
val;
next
=
null
;
}
//
public
Node()
{
data
=
default
(T);
next
=
null
;
}
//
数据域属性
public
T Data
{
get
{
return
data;
}
set
{
data
=
value;
}
}
//
引用域属性
public
Node
<
T
>
Next
{
get
{
return
next;
}
set
{
next
=
value;
}
}
}