对线性表(顺序表、链式表)的一些操作总结,也是应对即将到来的笔试
线性结构的特点:
(1)存在唯一的一个被称作“第一个”的数据元素
(2)存在唯一的一个被称作“最后一个”的数据元素
(3)除第一个之外,集合中的每个数据元素均只有一个前驱
(4)除最后一个之外,集合中每个数据元素均只有一个后继
一、线性表
线性表是最基本、最简单、也是最常用的一种数据结构。
1.1 线性表的顺序表示与实现(顺序表)
特点:逻辑关系上相邻的两个元素在物理位置上也是相邻的
,缺点:在插入和删除数据时,需要移动大量元素
顺序表的定义:
vc6.0下顺利运行,代码1
main.cpp
#include
<stdio.h>
#include
<string.h>
#include
<stdlib.h>
#include
"SqList.h"
int
main()
{
SqList myList;
int
flag;
int
loc;
//
位置
int
len;
//
表的长度
ElemType e;
//
表中元素
e
while
(1)
{
printf(
"\n*****************************"
);
printf(
"\n* 1.
初始化线性表
"
);
printf(
"\n* 2.
创建线性表
"
);
printf(
"\n* 3.
遍历顺序表
"
);
printf(
"\n* 4.
线性表中插入元素
"
);
printf(
"\n* 5.
线性表中删除元素
"
);
printf(
"\n* 6.
查找第
i
个元素
"
);
printf(
"\n* 7.
查找元素
e"
);
printf(
"\n* 8.
显示线性表长度
"
);
printf(
"\n* 0.
结束程序运行
"
);
printf(
"\n***************************"
);
printf(
"\n
输入您所需操作
:"
);
scanf(
"%d"
,&flag);
switch
(flag)
{
case
1:
if
(OK==SqListInit(myList))
printf(
"\n
成功完成线性表初始化
\n"
);
else
printf(
"\n
操作失败,内存溢出
\n"
);
break
;
case
2:
CreateList(myList);
break
;
case
3:
printf(
"
遍历顺序表
"
);
SqListAll(myList);
break
;
case
4:
printf(
"\n
请输入插入位置:
"
);
scanf(
"%d"
,&loc);
printf(
"\n
请输入插入的元素
e
:
"
);
scanf(
"%d"
,&e);
if
(OK==SqListInsert(myList,loc,e))
printf(
"\n
操作成功
\n"
);
else
printf(
"\n
操作失败,插入位置不对
\n"
);
break
;
case
5:
printf(
"\n
输入删除位子:
"
);
scanf(
"%d"
,&loc);
if
(OK==SqListDelete(myList,loc,e))
printf(
"\n
操作成功
"
);
else
printf(
"\n
操作失败,可能位置不合理
\n"
);
break
;
case
6:
printf(
"\n
查找的元素位置是:
"
);
scanf(
"%d"
,&loc);
if
(OK==GetElem(myList,loc,e))
printf(
"\n
操作成功
\n"
);
else
printf(
"\n
操作失败,可能查找位置不合理
\n"
);
break
;
case
7:
printf(
"\n
输入要查找的元素
e:"
);
scanf(
"%d"
,&e);
loc=LocateElem(myList,e);
if
(!loc)
printf(
"\n
表中不存在元素
%d"
,e);
else
printf(
"\n
找到了,元素
%d
在表中的位置是:
%d\n"
,e,loc);
break
;
case
8:
printf(
"\n
表的长度为:
%d\n"
,len=SqListLength(myList));
break
;
case
0:
exit(0);
default
:
printf(
"
输入的菜单号有误!
\n"
);
break
;
}
}
return
0;
}
SqList.h
#ifndef
SQLIST_H
#define
SQLIST_H
#include
<stdio.h>
#include
<string.h>
#define
LIST_INIT_SIZE 5
#define
LISTINCREMENT 1
#define
OVERFLOW -2
#define
OK 1
#define
ERROR 0
typedef
int
Status;
typedef
int
ElemType;
//
这里元素类型时
int
型
typedef
struct
{
ElemType *elem;
int
length;
int
listsize;
}SqList;
Status SqListInit(SqList &L);
//
初始化
void
CreateList(SqList &L);
Status SqListLength(SqList L);
//
返回顺序表的长度
Status SqListInsert(SqList &L,
int
i,ElemType e);
//
插入元素
Status SqListDelete(SqList &L,
int
i,ElemType e);
//
删除元素
Status GetElem(SqList L,
int
i,ElemType e);
//
得到第
i
个元素返回给
e
int
LocateElem(SqList L,ElemType e);
//
查找
void
SqListAll(SqList L);
#endif
SqList.cpp
#include
"SqList.h"
#include
<stdlib.h>
Status SqListInit(SqList &L)
//
初始化
{
L.elem=(ElemType *)malloc(LIST_INIT_SIZE*
sizeof
(ElemType));
if
(L.elem==NULL)
return
OVERFLOW;
L.length=0;
L.listsize=LIST_INIT_SIZE;
return
OK;
}
void
CreateList(SqList &L)
//
赋值
{
printf(
"
创建顺序表
\n"
);
printf(
"
请输入元素个数:
"
);
int
count;
scanf(
"%d"
,&count);;
for
(
int
i=0;i<count;++i)
{
printf(
"
请输入第
i
个数:
"
);
scanf(
"%d"
,&L.elem[i]);
++L.length;
}
/*int i;
int a[5]={34,23,67,43};
L.length=0;
for(i=1;i<=4;i++)
{
if(SqListInsert(L,i,a[i-1])==0)
return ERROR;
}
return OK;*/
}
Status SqListLength(SqList L)
{
return
(L.length);
}
Status SqListInsert(SqList &L,
int
i,ElemType e)
//
顺序表中的第
i
个位置,插入元素e
{
ElemType *newbase;
if
(i<1||i>L.length+1)
return
ERROR;
if
(L.length>=L.listsize)
{
newbase=(ElemType *)realloc(L.elem,(LIST_INIT_SIZE+LISTINCREMENT)*
sizeof
(ElemType));
L.elem=newbase;
L.listsize+=LISTINCREMENT;
}
ElemType *q=&(L.elem[i-1]);
//这里是取地址
ElemType *p;
for
(p=&(L.elem[L.length-1]);p>=q;p--)
*(p+1)=*p;
*q=e;
++L.length;
return
OK;
}
Status SqListDelete(SqList &L,
int
i,ElemType e)
//
删除第
i
个元素,应用
e
返回其值
{
if
(i<1||i>L.length)
return
OVERFLOW;
ElemType *q=&(L.elem[i-1]);
ElemType *p=L.elem+L.length-1;
//
p=&(L.elem[L.length-1])
for
(++q;q<=p;q++)
*(q-1)=*q;
--L.length;
return
OK;
}
Status GetElem(SqList L,
int
i,ElemType e)
//
得到第
i
个元素,将其赋给
e
{
int
j;
if
(i<1||i>L.length)
return
ERROR;
for
(j=1;j<=i;j++)
L.elem++;
e=*L.elem;
return
OK;
}
int
LocateElem(SqList L,ElemType e)
//
找到
L
中第一个和
e
相同的元素
{
int
j;
//ElemType *p_elem;
for
(j=1;j<=L.length;j++)
{
if
(*L.elem==e)
{
// p_elem=L.elem;
return
j;
}
else
L.elem++;
}
return
0;
}
void
SqListAll(SqList L)
//
遍历输出
{
int
i;
for
(i=1;i<=L.length;i++)
printf(
"%d\n"
,*(L.elem++));
}
|
代码2
/* Linear Table On Sequence Structure */
#include
<stdio.h>
#include
<stdlib.h>
#include
<string.h>
#define
LIST_INIT_SIZE 100
#define
LISTINCREMENT 10
#define
OK 1
#define
TRUE 1
#define
FALSE -1
#define
ERROR 0
#define
OVERFLOW -2
/*------------------------------------------------------*/
typedef
int
status;
typedef
struct
Elemtype{
int
item1;
}Elemtype;
typedef
struct
SqList{
Elemtype * elem;
int
length;
int
listsize;
}SqList;
status IntiaList(SqList *L);
status DestroyList(SqList * L);
status ClearList(SqList *L);
status ListEmpty(SqList L);
int
ListLength(SqList L);
status GetElem(SqList L,
int
i,Elemtype * e);
status LocatElem(SqList L,Elemtype e,status(*compare)(Elemtype x,Elemtype y));
status ListInsert(SqList * L,
int
i, Elemtype e);
status ListDelete(SqList * L,
int
i, Elemtype * e);
status ListTrabverse(SqList L,
void
(* visit)(Elemtype e));
status compare(Elemtype x, Elemtype y);
void
visit(Elemtype e);
void
menu(
void
);
int
ListSave(SqList L);
void
ListLoad(SqList L);
void
main(
void
){
int
t,i;
char
c;
SqList L;
Elemtype e;
int
op=0;
L.elem=NULL;
L.elem=(Elemtype *) malloc(
sizeof
(Elemtype)*10);
do
{
system(
"cls"
);
menu();
printf(
"
请输入你的选择
[0-12]
:
"
);
c: scanf(
"%d"
,&op);
switch
(op){
case
1: printf(
"\n here is IntiaList(),which being realized\n"
);
getchar();
IntiaList( &L);
getchar();
break
;
case
2: printf(
"\n here is DestroyList(),which being realized\n"
);
getchar();
DestroyList( &L);
break
;
case
3: printf(
"\n here is ClearList(),which being realized\n"
);
getchar();
ClearList( &L);
break
;
case
4: printf(
"\n here is ListEmpty(),which being realized\n"
);
getchar();
t=ListEmpty( L);
if
(t==1)
printf(
"\n
线性表为空!
"
);
else
if
(t==-1)
printf(
"\n
线性表不为空!
"
);
break
;
case
5: printf(
"\n here is ListLength() ,which being realized\n"
);
getchar();
t=ListLength( L);
printf(
"\n
线性表长度为
%d"
,t);
break
;
case
6: printf(
"\n here is GetElem(),which being realized\n"
);
getchar();
printf(
"
输入要取的元素位置
i : "
);
scanf(
"%d"
,&i);
getchar();
if
(GetElem( L,i,&e))
printf(
"\n
取出的元素为
%d"
,e.item1);
else
printf(
"\n ERROR!"
);
break
;
case
7: printf(
"\n here is LocatElem(),which being realized\n"
);
getchar();
printf(
"
输入要寻找的元素
: "
);
scanf(
"%d"
,&e);
getchar();
t=LocatElem( L, e, compare);
printf(
"\n
它的位置为
%d"
,t);
break
;
case
8: printf(
"\n here is ListSave(),which being realized\n"
);
ListSave( L);
getchar();
break
;
case
9: printf(
"\n here is ListInsert(),which being realized\n"
);
getchar();
printf(
"\n
输入你想插入的位置
i
:
"
);
scanf(
"%d"
,&i); getchar();
printf(
"\n
输入你想插入的元素
e
:
"
);
scanf(
"%d"
,&e); getchar();
if
(ListInsert( &L,i,e)){
printf(
"\n
插入成功!现在的线性表为:
"
);
ListTrabverse( L, visit);
}
else
printf(
"\n
插入失败!
"
);
break
;
case
10: printf(
"\n here is ListDelete(),which being realized\n"
);
getchar();
printf(
"\n
输入你想删除的元素位置
i
:
"
);
scanf(
"%d"
,&i); getchar();
if
(ListDelete( &L,i,&e)){
printf(
"\n
删除成功!现在的线性表为:
"
);
ListTrabverse( L, visit);
}
else
printf(
"\n
删除失败!
"
);
break
;
case
11: printf(
"\n here is ListTrabverse(),which being realized\n"
);
if
(!L.elem)
printf(
"\n
线性表不存在!
\n"
);
else
if
(!ListTrabverse(L,visit))
printf(
"\n
线性表为空!
\n"
);
getchar();
break
;
case
0: printf(
"\n ---------------Welcome again!--------------------\n"
);
exit(0);
default
: printf(
"
错误!
\n
请再次输入:
"
);
goto
c;
}
getchar();
}
while
(op);
}
status IntiaList(SqList *L){
/*
构造一个空的线性表
L*/
int
i;
char
c;
SqList *elem;
L->elem=(Elemtype*)malloc(LIST_INIT_SIZE*
sizeof
(Elemtype));
if
(!L->elem)exit(OVERFLOW);
/*
存储分配失败
*/
L->length=0;
/*
空表长度为
*/
L->listsize=LIST_INIT_SIZE;
/*
初始存储容量
*/
printf(
"\n
输入线性表长度:
"
);
scanf(
"%d"
,&L->length);
if
(L->length!=0){
/*
按序依次输入元素
*/
printf(
"\n
依次输入元素,回车结束:
"
);
for
( i=0;i<L->length;i++)
scanf(
"%d"
,&L->elem[i]);
}
printf(
"\n\n
创建成功!
"
);
return
OK;
}
status DestroyList(SqList *L){
/*
线性表
L
已存在
*/
/*
销毁线性表
L*/
if
(!L->elem)
/*
已经销毁
*/
return
ERROR;
free(L->elem);
L->elem = NULL;
/*
表置空
*/
printf(
"\n
销毁成功!
"
);
return
OK;
}
status ClearList(SqList *L){
/*
线性表
L
已存在
*/
/*
将
L
重置为空表
*/
if
(!L->elem)
/*L
不存在
*/
return
ERROR;
L->length = 0;
printf(
"\n
置空成功!
"
);
return
OK;
}
status ListEmpty(SqList L){
/*
线性表
L
已经存在
*/
/*
判断
L
是否为空,空返回
true,
否则
false*/
if
(L.length<0||L.length>L.listsize||!(L.elem))
return
ERROR;
if
(L.length==0)
return
TRUE;
return
FALSE;
}
int
ListLength(SqList L){
/*
线性表
L
已经存在
*/
/*
返回
L
中元素的个数
*/
if
(L.length <0||L.length>L.listsize||!(L.elem))
return
ERROR;
return
L.length;
}
status GetElem(SqList L,
int
i,Elemtype *e){
/*
线性表
L
已经存在
*/
/*
用
e
返回
L
中的第
i
个元素的值
*/
if
(i<1||i>L.length||!L.elem)
return
ERROR;
*e=L.elem[i-1];
/*
与
Elemtype
相关
*/
return
TRUE;
}
status LocatElem(SqList L,Elemtype e,status(*compare)(Elemtype,Elemtype)){
/*
线性表
L
已经存在
,compare(
)是数据元素判定函数
*/
/*
返回
L
中第一个与
e
满足关系
compare()
的数据的位序,若不存在,返回值为
*/
int
i;
if
(!L.elem)
return
ERROR;
for
(i=0;i<L.length;i++) {
if
(compare(e,L.elem[i])==TRUE)
/*
与
Elemtype
相关
*/
return
i+1;
}
}
status ListInsert(SqList *L,
int
i, Elemtype e){
/*
在
L
中第
i
个位置之前插入新的数据元素
e
,
L
的长度加
*/
Elemtype *newbase,*p,*q;
if
(!L->elem)
return
ERROR;
if
(i < 1 || i > L->length + 1)
return
ERROR;
if
(L->length >= L->listsize) {
newbase=(Elemtype*)realloc(L->elem,(L->listsize+LISTINCREMENT)*
sizeof
(Elemtype));
if
(!newbase) exit(OVERFLOW);
L->elem = newbase;
L->listsize += LISTINCREMENT;
}
p=&(L->elem[i-1]);
/*p
为插入的地址
*/
for
(q=&(L->elem[L->length-1]);q>=p;q--)
*(q+1) = *q;
*p = e;
++L->length;
return
OK;
}
status ListDelete(SqList *L,
int
i,Elemtype *e){
/*
在顺序表
L
中删除第
i
个元素,并用
e
返回其值
*/
Elemtype *p,*q;
if
(i<1||i>L->length||!L->elem)
return
ERROR;
/*i
值不合法
*/
p=&(L->elem[i-1]);
/*p
为被删除元素的位置
*/
e=p;
/*
被删除元素的值赋给
e*/
q=L->elem+L->length-1;
/*
表位元素的位置
*/
for
(++p;p<=q;++p)
*(p-1)=*p;
/*
被删除元素之后的元素左移
*/
--L->length;
return
OK;
}
status ListTrabverse(SqList L,
void
(*visit)(Elemtype e)){
/*
遍历顺序表
L
,并打印输出
*/
int
i;
if
(!L.length)
return
ERROR;
printf(
"\n-------------
线性表所有元素如下
---------------\n"
);
for
(i=0;i<L.length;i++)
visit(L.elem[i]);
return
TRUE;
}
void
visit(Elemtype e){
printf(
"%d "
,e.item1);
}
/*------------------------------------------------------*/
void
menu(
void
){
printf(
"\n\n"
);
printf(
"
顺序线性表操作菜单选项
\n"
);
printf(
" ------------------------------------------------\n"
);
printf(
" 1.
创建线性表
7.
元素定位
\n"
);
printf(
" 2.
销毁线性表
8.
保存线性表
\n"
);
printf(
" 3.
清空线性表
9.
插入元素
\n"
);
printf(
" 4.
判断空表
10.
删除元素
\n"
);
printf(
" 5.
求表长度
11.
遍历线性表
\n"
);
printf(
" 6.
取元素值
0.
退出
\n"
);
printf(
" ------------------------------------------------\n"
);
}
status compare(Elemtype x, Elemtype y){
if
(x.item1==y.item1)
return
TRUE;
else
if
(x.item1!=y.item1)
return
FALSE;
}
int
ListSave(SqList L) {
int
i;
FILE *fout;
if
((fout = fopen(
"f:\\SqList.dat"
,
"w+"
)) == NULL) {
printf(
"ERROR!\n"
);
return
ERROR;
}
fprintf(fout,
"%d\t%d\n"
, L.length, L.listsize);
for
(i=0; i < ListLength(L); i++){
fprintf(fout,
"%d\t"
, L.elem[i]);
}
fclose(fout);
printf(
"\n
保存成功!
"
);
return
OK;
}
void
ListLoad(SqList L){
int
i;
FILE *fin;
/*
指向文件的指针
*/
fin=fopen(
"f:\\SqList.dat"
,
"r+b"
);
if
(!feof(fin))
fread(&L.length,
sizeof
(SqList),1,fin);
fread(&L.listsize,
sizeof
(SqList),1,fin);
for
(i=0; i<L.length,!feof(fin); i++){
fread(&L.elem[i],
sizeof
(SqList),1,fin);
if
(!feof(fin))
{
printf(
"%d\t"
,L.elem[i]);
}
}
/*
读入完毕,关闭文件
*/
fclose(fin);
printf(
"\n
载入成功!
"
);
return
OK;
}
|
1.2 线性表的链式表示与实现(链式表)
特点:用任意的存储单元存储线性表的数据元素
定义:
1.2.1 线性链表(单链表)
一个结点中只含有一个指针域,称为线性链表或单链表
main.cpp
#include
<stdio.h>
#include
<string.h>
#include
"List.h"
#include
<stdlib.h>
int
main()
{
LinkList myList;
int
loc;
int
flag,len;
ElemType e;
while
(1)
{
printf(
"\n****************************************"
);
printf(
"\n* 1.
初始化线性表
"
);
printf(
"\n* 2.
创建链表
"
);
printf(
"\n* 3.
遍历顺序表
"
);
printf(
"\n* 4.
线性表中第
i
个位置插入元素
"
);
printf(
"\n* 5.
线性表中删除第
i
个元素
"
);
printf(
"\n* 6.
查找第
i
个元素
"
);
printf(
"\n* 8.
显示线性表长度
"
);
printf(
"\n* 0.
结束程序运行
"
);
printf(
"\n***************************************"
);
printf(
"\n
输入您所需操作
:"
);
scanf(
"%d"
,&flag);
switch
(flag)
{
case
1:
if
(OK==ListInit(myList))
printf(
"
初始化线性表成功!
\n"
);
break
;
case
2:
if
(OK==CreateList(myList))
printf(
"
单链表创建成功!
\n"
);
break
;
case
3:
printf(
"
遍历链表
"
);
ListAll(myList);
break
;
case
4:
printf(
"
输入插入的位置:
\n"
);
scanf(
"%d"
,&loc);
printf(
"
输入插入的元素:
\n"
);
scanf(
"%d"
,&e);
if
(OK==ListInsert(myList,loc,e))
{
printf(
"
插入元素
%d
后各值为:
\n"
,e);
ListAll(myList);
}
else
printf(
"
操作错误!
\n"
);
break
;
case
5:
printf(
"
输入删除的位置:
\n"
);
scanf(
"%d"
,&loc);
if
(OK==ListDelete(myList,loc,e))
{
printf(
"
删除元素
%d
后各值为:
\n"
,e);
ListAll(myList);
}
else
printf(
"
操作错误!
\n"
);
break
;
case
6:
printf(
"
输入查找的元素位置:
\n"
);
scanf(
"%d"
,&loc);
if
(OK==GetElem(myList,loc,e))
{
printf(
"
元素为
%d:"
,e);
}
break
;
case
7:
printf(
"
输入查找的元素:
\n"
);
scanf(
"%d"
,&e);
loc=LocateElem(myList,e);
printf(
"e
位置在
%d
处
"
,loc);
case
8:
printf(
"
链表长度是:
%d\n"
,len=ListLength(myList));
break
;
case
0:
exit(0);
}
}
return
0;
}
List.h
#include
<stdio.h>
#include
<string.h>
#define
OVERFLOW -2
#define
OK 1
#define
ERROR 0
typedef
int
Status;
typedef
int
ElemType;
typedef
struct
LNode
{
ElemType data;
struct
LNode *next;
}LNode,*LinkList;
Status ListInit(LinkList &L);
Status CreateList(LinkList &L);
void
ListAll(LinkList L);
int
ListLength(LinkList L);
Status ListInsert(LinkList &L,
int
i,ElemType e);
Status ListDelete(LinkList &L,
int
i,ElemType e);
Status GetElem(LinkList L,
int
i,ElemType &e);
int
LocateElem(LinkList L,ElemType e);
List.cpp
#include
"List.h"
#include
<stdlib.h>
Status ListInit(LinkList &L)
{
L=(LinkList)malloc(
sizeof
(LNode));
if
(!L)
exit(OVERFLOW);
L->next=NULL;
return
OK;
}
Status CreateList(LinkList &L)
{
printf(
"
输入要插入的结点个数:
\n"
);
int
count;
scanf(
"%d"
,&count);
LinkList p;
for
(
int
i=count;i>0;--i)
{
p=(LinkList)malloc(
sizeof
(LNode));
scanf(
"%d"
,&p->data);
p->next=L->next;
L->next=p;
}
return
OK;
}
void
ListAll(LinkList L)
{
LinkList p;
for
(p=L->next;p;p=p->next)
printf(
"%d\n"
,p->data);
printf(
"\n"
);
}
int
ListLength(LinkList L)
{
int
i=0;
LinkList p;
for
(p=L->next;p;p=p->next)
i++;
return
i;
}
Status ListInsert(LinkList &L,
int
i,ElemType e)
//
在第
i
个位置之前插入
e
{
LinkList p,s;
int
j=0;
p=L;
while
(p&&j<i-1)
//
带头结点的单链表中找到第
i-1
个结点,退出
while
时
j=i-1
{p=p->next;++j;}
if
(!p||j>i-1)
return
ERROR;
s=(LinkList)malloc(
sizeof
(LNode));
s->data=e;
s->next=p->next;
p->next=s;
return
OK;
}
Status ListDelete(LinkList &L,
int
i,ElemType e)
{
LinkList p=L,q;
int
j=0;
while
(p->next&&j<i-1)
{p=p->next;++j;}
if
(!(p->next)||j>i-1)
return
ERROR;
q=p->next;
p->next=q->next;
e=q->data;
free(q);
return
OK;
}
Status GetElem(LinkList L,
int
i,ElemType &e)
{
LinkList p=L->next;
int
j=1;
while
(p&&j<i)
{p=p->next;++j;}
if
(!p||j>i)
return
ERROR;
e=p->data;
return
OK;
}
int
LocateElem(LinkList L,ElemType e)
{
LinkList p=L->next;
int
i=0;
while
(p)
{
++i;
if
(p->data==e)
{
return
i;}
p=p->next;
}
return
0;
}
|