一、线性表
定义:线性表是一种可以在任意位置进行插入和删除元素操作的、由n(n≥0)个相同类型元素
组成的线性结构。其主要操作特点是可以在任意位置插入和删除一个数据元素。
线性表有顺序存储结构和链式存储结构存储。顺序存储的有顺序表,链式存储有单链表、循环单链表、双向循环链表。
二、顺序表
顺序表的存储结构:
(2.1)顺序表操作的实现
(2.1.1)定义顺序表结构体
//定义顺序表结构体
typedef struct {
DataType list[MAXSIZE]; //DataType是抽象元素的数据类型:typedef int DataType
int size;
}SeqList;
(2.1.2)初始化ListInitiate(L)
//初始化
void ListInitiate(SeqList *L)
{
L->size=0;
}
(2.1.3)求当前元素个数ListLength(L)
int ListLength(SeqList L)
{
return L.size;
}
(2.1.4)插入元素ListInsert(L,i,x)
//插入元素
int ListInsert(SeqList *L,int i,DataType x)
{
int j;
if(L->size>=MAXSIZE)
{
printf("List is full!\n");
return 0;
}
else if(i<0||i>L->size)
{
printf("Insert Param Error!\n");
return 0;
}
else
{
for(j=L->size;j>i;j--)
{
L->list[j]=L->list[j-1];
}
L->list[i]=x;
L->size++;
return 1;
}
}
(2.1.5)删除元素ListDelete(L,i,x)
//删除元素
int ListDelete(SeqList *L,int i,DataType *x)
{
int j;
if(L->size<=0)
{
printf("List is null!\n");
return 0;
}
else if(i<0||i>L->size-1)
{
printf("Param Error!\n");
return 0;
}
else
{
*x=L->list[i];
for(j=i+1;j<=L->size-1;j++)
{
L->list[j-1]=L->list[j];
}
L->size--;
return 1;
}
}
(2.1.6)取元素ListGet(L,i,x)
int ListGet(SeqList L,int i ,DataType *x)
{
if(i<0||i>L.size-1)
{
printf("Param Error!\n");
return 0 ;
}
else
{
*x=L.list[i];
return 1;
}
}
完整的代码
#include<stdio.h>
#include<stdlib.h>
//typedef int DataType;
#define DataType int
//using DataType=int
#define MAXSIZE 100
typedef struct {
DataType list[MAXSIZE];
int size;
}SeqList;
void ListInitiate(SeqList *L)
{
L->size=0;
}
int ListLength(SeqList L)
{
return L.size;
}
int ListInsert(SeqList *L,int i,DataType x)
{
int j;
if(L->size>=MAXSIZE)
{
printf("List is full!\n");
return 0;
}
else if(i<0||i>L->size)
{
printf("Insert Param Error!\n");
return 0;
}
else
{
for(j=L->size;j>i;j--)
{
L->list[j]=L->list[j-1];
}
L->list[i]=x;
L->size++;
return 1;
}
}
int ListDelete(SeqList *L,int i,DataType *x)
{
int j;
if(L->size<=0)
{
printf("List is null!\n");
return 0;
}
else if(i<0||i>L->size-1)
{
printf("Param Error!\n");
return 0;
}
else
{
*x=L->list[i];
for(j=i+1;j<=L->size-1;j++)
{
L->list[j-1]=L->list[j];
}
L->size--;
return 1;
}
}
int ListGet(SeqList L,int i ,DataType *x)
{
if(i<0||i>L.size-1)
{
printf("Param Error!\n");
return 0 ;
}
else
{
*x=L.list[i];
return 1;
}
}
void main(int argc,int argv[])
{
SeqList myList;
int i,x;
ListInitiate(&myList);
for(i=0;i<10;i++)
{
ListInsert(&myList,i,i+1);
//ListInsert(&myList,i,i++);//会报错
}
ListDelete(&myList,4,&x);
printf("%d\n",x);
for(i=0;i<ListLength(myList);i++)
{
ListGet(myList,i,&x);
printf("%d ",x);
}
}
//输出结果
5
1 2 3 4 6 7 8 9 10
三、链表
(3.1)单链表
(3.1.1)单链表操作的实现
(3.1.1.1)单链表的结点结构体设计
typedef struct Node{
DataType data;
struct Node *next;
}SLNode;
(3.1.1.2)单链表的初始化ListInitiate(SLNode **head)
//初始化
void ListInitiate(SLNode **head){
//申请头结点 ,由head指示其地址
*head=(SLNode*)malloc(sizeof(SLNode));
//置结束结点为空
(*head)->next=NULL;
}
(3.1.1.3)求当前元素个数ListLength(SLNode *head)
//求当前元素个数
int ListLength(SLNode *head){
//p指向头结点
SLNode *p=head;
//size初始为0
int size=0;
//循环计数
while(p->next!=NULL){
p=p->next;
size++;
}
return size;
}
(3.1.1.4)向链表中插入元素ListInsert(SLNode *head,int i,DataType x)
//插入元素
int ListInsert(SLNode *head,int i,DataType x){
//在带头结点的单链表head的第i(0~size)个结点前插入一个存放元素x的结点
//插入成功返回 1,插入失败返回0
SLNode *p,*q;
int j;
p=head;
j=-1;
while(p->next!=NULL&&j<=i-1){
//最终让指针p指向第i-1个结点
p=p->next;
j++;
}
if(j!=i-1){
printf("插入元素位置参数错误!\n");
return 0;
}
q=(SLNode*)malloc(sizeof(SLNode));
q->data=x;
q->next=p->next;
p->next=q;
return 1;
}
(3.1.1.5)删除ListDelete(SLNode *head,int i,DataType *x)
//删除
int ListDelete(SLNode *head,int i,DataType *x){
//删除带头结点单链表head的第i(0~size-1)个结点
//被删除的结点的数据域值由x带回,删除成功返回1,删除失败返回0
SLNode *p,*s;
int j;
p=head;
j=-1;
while(p->next!=NULL&&p->next->next!=NULL&&j<i-1){
p=p->next;
j++;
}
if(j!=i-1){
printf("删除元素位置参数错误!\n");
return 0;
}
s=p->next;
*x=s->data;
p->next=p->next->next;
free(s);
return 1;
}
(3.1.1.6)取元素ListGet(SLNode *head,int i, DataType *x)
//取元素
int ListGet(SLNode *head,int i,DataType *x){
SLNode *p;
int j;
p=head;
j=-1;
while(p->next!=NULL&&j<i){
p=p->next;
j++;
}
if(j!=i){
printf("取元素位置参数错误!\n");
return 0;
}
*x=p->data;
return 1;
}
(3.1.1.7)撤销单链表Destroy(SLnode **head)
//撤销单链表
void Destroy(SLNode **head){
SLNode *p,*p1;
p=*head;
while(p!=NULL){
p1=p;
p=p->next;
free(p1);
}
*head=NULL;
}
完整代码
#include<stdio.h>
#include<malloc.h>
typedef int DataType;
typedef struct Node{
DataType data;
struct Node *next;
}SLNode;
//初始化
void ListInitiate(SLNode **head){
//申请头结点 ,由head指示其地址
*head=(SLNode*)malloc(sizeof(SLNode));
//置结束结点为空
(*head)->next=NULL;
}
//求当前元素个数
int ListLength(SLNode *head){
//p指向头结点
SLNode *p=head;
//size初始为0
int size=0;
//循环计数
while(p->next!=NULL){
p=p->next;
size++;
}
return size;
}
//插入元素
int ListInsert(SLNode *head,int i,DataType x){
//在带头结点的单链表head的第i(0~size)个结点前插入一个存放元素x的结点
//插入成功返回 1,插入失败返回0
SLNode *p,*q;
int j;
p=head;
j=-1;
while(p->next!=NULL&&j<=i-1){
//最终让指针p指向第i-1个结点
p=p->next;
j++;
}
if(j!=i-1){
printf("插入元素位置参数错误!\n");
return 0;
}
q=(SLNode*)malloc(sizeof(SLNode));
q->data=x;
q->next=p->next;
p->next=q;
return 1;
}
//删除
int ListDelete(SLNode *head,int i,DataType *x){
//删除带头结点单链表head的第i(0~size-1)个结点
//被删除的结点的数据域值由x带回,删除成功返回1,删除失败返回0
SLNode *p,*s;
int j;
p=head;
j=-1;
while(p->next!=NULL&&p->next->next!=NULL&&j<i-1){
p=p->next;
j++;
}
if(j!=i-1){
printf("删除元素位置参数错误!\n");
return 0;
}
s=p->next;
*x=s->data;
p->next=p->next->next;
free(s);
return 1;
}
//取元素
int ListGet(SLNode *head,int i,DataType *x){
SLNode *p;
int j;
p=head;
j=-1;
while(p->next!=NULL&&j<i){
p=p->next;
j++;
}
if(j!=i){
printf("取元素位置参数错误!\n");
return 0;
}
*x=p->data;
return 1;
}
//撤销单链表
void Destroy(SLNode **head){
SLNode *p,*p1;
p=*head;
while(p!=NULL){
p1=p;
p=p->next;
free(p1);
}
*head=NULL;
}
int main(int argc, char *argv[]) {
SLNode *head;
int i,x;
ListInitiate(&head);
for(i=0;i<10;i++){
ListInsert(head,i,i+1);
}
ListDelete(head,4,&x);
for(i=0;i<ListLength(head);i++){
ListGet(head,i,&x);
printf("%d ",x);
}
Destroy(&head);
return 0;
}
//输出结果
1 2 3 4 6 7 8 9 10