龙空技术网

数据结构入门(二)

创业风口 120

前言:

眼前姐妹们对“typedef struct lnode list”大约比较注重,同学们都需要学习一些“typedef struct lnode list”的相关知识。那么小编同时在网摘上搜集了一些关于“typedef struct lnode list””的相关资讯,希望同学们能喜欢,兄弟们一起来了解一下吧!

2.1 线性表及其实现

类型名称:( 线性表(List )

数据对象集:是 线性表是 n (≥0) 个元素构成的有序序列( a 1 , a 2 , ,a n )

操作集:表 线性表L   List ,整数i 表示位置,元素X   ElementType ,

线性表基本操作主要有:

1 、List MakeEmpty(): : 初始化一个空线性表L ;

2 、ElementType FindKth( int K, List L ) :根据位序K ,返回相应元素 ;

3 、int Find( ElementType X, List L ) :在线性表L 中查找X 的第一次出现位置;

4 、void Insert( ElementType X, int i, List L) :在位序i 前插入一个新元素X ;

5 、void Delete( int i, List L ) :删除指定位序i 的元素;

6 、int Length( List L ) :返回线性表L 的长度n 。

线性表的抽象数据类型描述

利用数组的 连续存储空间顺序存放素 线性表的各元素

typedef struct LNode *List;

struct LNode{

ElementType Data[MAXSIZE];

int Last;

} ;

struct LNode L;

List PtrL;

下标i 0 1 …… i-1 i …… n-1 …… MAXSIZE-1

Data a a 1 1 a a 2 2 …… a a i i a a i+1

…… a a n n …… - -

t Last

访问下标为 i 的元素:L.Data[i] 或 PtrL->Data[i]

线性表的长度:L.Last+1 或 PtrL->Last+1

线性表的顺序存储实现

1. 初始化(建立空的顺序表)

  主要操作的 实现

List MakeEmpty( ( ) )

{ { List PtrL; ;

PtrL = = (List ) ) malloc( ( sizeof( ( struct LNode) ) ) ); ;

PtrL- -> > Last = = - -1 1; ;

return PtrL; ;

} }

2. 查找

int Find( ElementType X, List PtrL ) )

{ { int i i = = 0 0; ;

while( ( i i <= PtrL- - >Last && PtrL- - >Data[i i ]!= X X ) )

i i ++; ;

if ( (i i > > PtrL- -> > Last) return - -1 1; ; /* 如果没找到 , 返回- -1 1 */

else return i i; ; /* 找到后返回的是存储位置 */

} }

查找成功的平均比较次数为

(n +1)/2 ,平均时间性能为

O(n) 。

下标

i i

0 0 1 1 …… i i- -1 1 i i …… n n- -1 1 …… MAXSIZE- -1 1

Data a a 1 1 a a 2 2 …… a a i i a a i+1

…… a a n n …… - -

t Last

下标

i i

0 0 1 1 …… i i- -1 1 i i 1 i+1 …… n … ……

SIZE

- -1 1

Data a a 1 1 a a 2 2 …… a a i i a a i+1

… …… a a n n … …… - -

t Last

3. 插入 (第 i (1≤i≤n+1) 个位置上插入一个值为X 的新元素)

先移动,再插入

X

void Insert( ElementType X, int i, List PtrL )

{ int j;

if ( PtrL->Last == MAXSIZE-1 ){ /* 表空间已满,不能插入*/

printf( "表满");

return;

}

if ( i < 1 || i > PtrL->Last+2) { /* 检查插入位置的合法性*/

printf( "位置不合法");

return;

}

for ( j = PtrL->Last; j >= i-1; j-- )

PtrL->Data[j+1] = PtrL->Data[j]; /* 将 a i ~ ~ a n 倒序向后移动*/

PtrL->Data[i-1] = X; /* 新元素插入*/

PtrL->Last++; /*Last 仍指向最后元素*/

return;

}

平均移动次数为 n /2, ,

平均时间性能为 O(n)

4. 删除 (删除表的第 i (1≤i≤n) 个位置上的元素)

后面的元素依次前移

void Delete( int i, List PtrL )

{ int j;

if( i < 1 || i > PtrL->Last+1 ) { /* 检查空表及删除位置的合法性*/

printf (“ 不存在第%d 个元素”, i );

return ;

}

for ( j = i; j <= PtrL->Last; j++ )

PtrL->Data[j-1] = PtrL->Data[j]; /* 将 a i+1 ~ ~ a n 动 顺序向前移动*/

PtrL->Last--; /*Last 仍指向最后元素*/

return;

}

平均移动次数为 (n-1) /2, ,

平均时间性能为 O(n)

4. 删除操作实现

不要求逻辑上相邻的两个元素物理上也相邻 ;通过“链”建

。 立起数据元素之间的逻辑关系。

• 插入、删除不需要移动数据元素,只需要修改“链”。 。

typedef struct LNode *List;

struct LNode{

ElementType Data;

List Next;

};

struct Lnode L;

List PtrL;

访问序号为 i 的元素?

求线性表的长度?

线性表的链式存储实现

1. 求表长

  主要操作的 实现

int Length ( List PtrL )

{ List p = PtrL; /* p 指向表的第一个结点*/

int j = 0;

while ( p ) {

p = p->Next;

j++; /* 当前p 指向的是第 j 个结点*/

}

return j;

}

时间性能为 O(n) 。

2. 查找

List FindKth( int K, List PtrL )

{ List p = PtrL;

int i = 1;

while (p !=NULL && i < K ){

p = p->Next;

i++;

}

if ( i == K ) return p;

/* 找到第K 个,返回指针 */

else return NULL;

/* 否则返回空 */

}

List Find( ElementType X, List PtrL )

{

List p = PtrL;

while ( p!=NULL && p->Data != X )

p = p->Next;

return p;

}

( (1 )按序号查找: FindKth; ( (2 )按值查找: Find

平均时间性能为 O(n)

3. 插入 (在第 i-1(1≤i≤n+1) 个结点后插入一个值为X 的新结点)

( (1 )先构造一个 新结点 ,用s 指向;

( (2 )再找到链表的第 i-1 个结点,用p 指向;

( (3 )然后修改指针,插入结点 ( p 之后插入新结点是 是 s)

head ……

p p

s s

s s- - >Next = p- - >Next;

p p- - >Next = s;

考 思考: 修改指针的两个步骤如果交换一下,将会发生什么?

3. 插入操作实现

List Insert( ElementType X, int i, List PtrL )

{ List p, s;

if ( i == 1 ) { /* 新结点插入在表头 */

s = (List)malloc(sizeof(struct LNode)); /* 申请、填装结点*/

s->Data = X;

s->Next = PtrL;

return s; /* 返回新表头指针*/

}

p = FindKth( i-1, PtrL ); /* 查找第i-1 个结点 */

if ( p == NULL ) { /* 第i-1 个不存在,不能插入 */

printf( "参数i 错");

return NULL;

}else {

s = (List)malloc(sizeof(struct LNode)); /* 申请、填装结点*/

s->Data = X;

s->Next = p->Next; /* 新结点插入在第i-1 个结点的后面*/

p->Next = s;

return PtrL;

}

}

平均查找次数为 n /2 ,平均

时间性能为 O(n)

( (1 )先找到链表的第 i-1 个结点,用p 指向;

( (2 )再用指针s 指向要被删除的结点(p 的下一个结点);

head ……

p p

s = p- - >Next;

4. 删除 (删除链表的第 i (1≤i≤n) 个位置上的结点)

( (3 )然后修改指针,删除s 所指结点;

( (4 )最后释放s 所指结点的空间。

p p- - >Next = s- - >Next;

free (s s ); ;

考 思考: 操作指针的几个步骤如果随意改变,将会发生什么?

List Delete( int i, List PtrL )

{ List p, s;

if ( i == 1 ) { /* 若要删除的是表的第一个结点 */

s = PtrL; /*s 指向第1 个结点*/

if (PtrL!=NULL) PtrL = PtrL->Next; /* 从链表中删除*/

else return NULL;

free(s); /* 释放被删除结点 */

return PtrL;

}

p = FindKth( i-1, PtrL ); /* 查找第i-1 个结点*/

if ( p == NULL ) {

printf(“ 第%d 个结点不存在”, i-1); return NULL;

} else if ( p->Next == NULL ){

printf(“ 第%d 个结点不存在”, i); return NULL;

} else {

s = p->Next; /*s 指向第i 个结点*/

p->Next = s->Next; /* 从链表中删除*/

free(s); /* 释放被删除结点 */

return PtrL;

}

}

平均查找次数为 n /2, ,

平均时间性能为 O(n)

标签: #typedef struct lnode list