一、顺序表
是在计算机内存中以数组的形式保存的线性表,是指用一组地址连续的存储单元依次存储数据元素的线性结构。线性表采用顺序存储的方式存储就称之为顺序表。顺序表是将
表中的结点依次存放在计算机内存中一组地址连续的存储单元中。
1、静态分配方式
#include <stdio.h>
#define MaxSize 10 //定义最大长度
typedef struct{
int data[MaxSize]; //存放数据元素
int length; //当前长度
}SqList; //顺序表的类型定义
void InitList(SqList &L){
for(int i=0; i<MaxSize; i++)
L.data[i]=0; //初始化为0
L.length=0; //初始长度为0
}
int main(){
SqList L;
InitList(L);
for(int i=0; i<MaxSize; i++)
printf("%d ", L.data[i]);
printf("length=%d", L.length);
return 0;
}
输出
0 0 0 0 0 0 0 0 0 0 length=0
--------------------------------
Process exited with return value 0
Press any key to continue . . .
2、动态分配方式
#include <stdio.h>
#include <stdlib.h>
#define InitSize 10 //默认最大长度
typedef struct{
int *data; //指示动态分配数组的指针
int MaxSize; //最大容量
int length; //顺序表的当前长度
}SeqList;
d InitList(SeqList &L){
//用 malloc 函数申请一片连续的存储空间
L.data=(int *)malloc(InitSize*sizeof(int));
L.length=0;
L.MaxSize=InitSize;
for(int i=0; i<InitSize; i++)
L.data[i]=0; //初始化为0
}
void IncreaseSize(SeqList &L, int len){
int *p=L.data;
L.data=(int *)malloc((L.MaxSize+len)*sizeof(int));
for(int i=0; i<L.length; i++){
L.data[i]=p[i]; //将数据复制到新区域
}
L.MaxSize=L.MaxSize+len; //扩大长度
free(p); //释放原来的内存空间
}
int main(){
SeqList L;
InitList(L);
for(int i=0; i<L.MaxSize; i++)
printf("%d ", L.data[i]);
printf("\n原来size=%d", L.MaxSize);
IncreaseSize(L, 5);
printf("\n当前size=%d\n", L.MaxSize);
return 0;
}
输出
0 0 0 0 0 0 0 0 0 0
原来size=10
当前size=15
--------------------------------
Process exited with return value 0
Press any key to continue . . .
3、插入
#include <stdio.h>
#define MaxSize 10 //定义最大长度
typedef struct{
int data[MaxSize]; //存放数据元素
int length; //当前长度
}SqList; //顺序表的类型定义
void InitList(SqList &L){
for(int i=0; i<MaxSize; i++)
L.data[i]=0; //初始化为0
L.length=0; //初始长度为0
}
bool ListInsert(SqList &L, int i, int e){
if(i<1 || i>L.length+1)
return false;
if(L.length>=MaxSize)
return false;
for(int j=L.length; j>=i; j--)//将第i个元素及之后的元素后移
L.data[j]=L.data[j-1];
L.data[i-1]=e; //在位置i处放入e
L.length++; //长度加1
return true;
}
int main(){
SqList L;
InitList(L);
ListInsert(L, 1, 3);
ListInsert(L, 1, 2);
for(int i=0; i<MaxSize; i++)
printf("%d ", L.data[i]);
return 0;
}
4、删除
//删除第i个元素,e保存删除的元素值
bool Listdelete(SqList &L,int i,int &e)
{
if(i < 1 || i > L.length + 1) //i有效性判断
return false;
e = L.data[i-1];
for(int j = i;j < L.length;j++){
L.data[j-1] = L.data[j];
}
L.length--;
return true;
}
二、链式表
线性表的链式存储又称单链表,它是指通过任意的存储单元来存储线性表的数据。注意此时的数据在物理地址上不在连续,内存是动态分配的,而且数据是存放在结点中,结点组成链表,每个节点分为数据域和指针域,所以我们在定义的时候,数据域来存放数据,指针域存放后面结点的地址(因为地址不连续。必须有一个变量来知道下一个结点在哪里)
1、求表长
int Length( List L )
{
int n=0;
if(L==NULL)return 0;
while(L!=NULL)
{
L=L->Next;
n++;
}
return n;
}
2、查找(按序号)
#include<iostream>
#include<stdlib.h>
using namespace std;
#define ERROR -1
typedef int ElementType;
typedef struct LNode *PtrToLNode;
struct LNode
{
ElementType Data;
PtrToLNode Next;
};
typedef PtrToLNode List;
List Read()
{
List L,p,q;
int num=0;
L=(List)malloc(sizeof(List));
q=L;
do
{
cin>>num;
p=(List)malloc(sizeof(List));
p->Data=num;
q->Next=p;
q=p;
}while(getchar()!='\n');
q->Next=NULL;
return L->Next;
}
ElementType FindKth(List L, int K)
{
if(L==NULL||K==0)
{
return ERROR;
}
List p=L;
for(int i=1;i<K;i++)
{
if(p->Next==NULL)
{
return ERROR;
}
p=p->Next;
}
return p->Data;
}
int main()
{
int N, K;
ElementType X;
List L=Read();
cin>>N;
while(N--)
{
cin>>K;
X=FindKth(L,K);
if(X!=ERROR)
{
cout<<X<<" ";
}
else
{
cout<<"NA"<<" ";
}
}
return 0;
}
3、插入
头插法
void insertNodeByHead(struct Node* headNode, int data) {
struct Node* newNode = createNode(data);
newNode->next = headNode->next;
headNode->next = newNode;
}
尾插法
void insertNodeByTail(struct Node* headNode, int data) {
struct Node* newNode = createNode(data);
while (headNode->next != NULL)
{
headNode = headNode->next;//找到最后一个节点
}
headNode->next = newNode;
newNode->next = NULL;
}
4、删除
void deleteNodeByAppoin(struct Node* headNode, int posDate) {
//从headNode->next开始找posNode这个节点对应的数据
struct Node* posNode = headNode->next;
struct Node* posNodeFront = headNode;
if (posNode == NULL) {
printf("无法删除,链表为空\n");
}
else {
while (posNode->data != posDate) {
posNodeFront = posNode;//前面位置到达了后面节点的位置
posNode = posNodeFront->next;//后面位置变成了原来位置的下一个
if (posNode == NULL) {
printf("未找到指定位置,无法删除\n");
break;
}
}
posNodeFront->next = posNode->next;
free(posNode);
}
}
5、添加元素
Status InsertLinkList(LinkList * L,int i,ElemType e)
{
int j = 1;
LinkList p,q;
p = *L;
while(p && j < i)
{
p = p->next;
j++;
}
if(!p || j > i)
return ERROR;
q = (LinkList)malloc(sizeof(Node));
q->next = p->next;
p->next = q;
q->data = e;
return OK;
}