作者:MiTu_-_
基本数据结构
1.顺序表
是一种用动态分配的一维数组的线性顺序表,可以随机存储。
//名称:SqList()
//功能:线性顺序表
//说明:由于线性表的长度可变,且最大存储空间随问题不同而不同,所以用动态分配的一维数组
#include <stdio.h>
#include <stdlib.h>
#define OK 1
#define ERROR 0
#define LIST_SIZE 100
#define LIST_INCREMENT_SIZE 20
typedef int Status;
//链表定义
typedef int LT; //ListElemType
typedef struct {
LT * data; //基址
int length; //当前线性表长度
int listsize; //当前分配的存储容量
} SqList;
//链表操作
Status Init_SqList(SqList * L);
Status Insert_SqList(SqList * L, int i, LT e);
Status Delete_SqList(SqList * L, int i, LT * e);
Status Traverse_SqList(SqList L);
int Locate_data(SqList L, LT e);
int main(void)
{
int pos;
LT e;
SqList L;
Init_SqList(&L);
Insert_SqList(&L, 1, 1);
Insert_SqList(&L, 2, 10);
// Delete_SqList(&L, 2, &e);
Traverse_SqList(L);
pos = Locate_data(L, 10);
return 0;
}
Status Init_SqList(SqList * L)
{
int i, n;
L->data = (LT *)malloc(LIST_SIZE * sizeof(LT));
if (!L->data)
return ERROR;
printf("请输入链表长度:");
scanf("%d", &n);
printf("请输入%d个链表元素:", n);
for (i = 0; i < n; ++i)
scanf("%d", &L->data[i]);
L->length = n; //链表长度为n
L->listsize = LIST_SIZE;
return OK;
}
Status Insert_SqList(SqList * L, int n, LT e)
{
//在线性顺序表L中第n个位置之前插入元素e,位置为 1 ~ L->length
LT * newbase; //以备增加空间
int i;
if (n < 1 || n > L->length + 1)
return ERROR;
if (L->length >= L->listsize) //当前存储空间已满,增加分配
{
newbase = (LT *)realloc(L->data, (L->listsize + LIST_INCREMENT_SIZE) * sizeof(LT));
if (!newbase)
return ERROR;
L->data = newbase;
L->listsize += LIST_INCREMENT_SIZE;
}
for (i = L->length - 1; i >= n - 1; --i) //插入位置元素之后的元素后移
L->data[i + 1] = L->data[i];
L->data[n - 1] = e;
++L->length;
return OK;
}
Status Delete_SqList(SqList * L, int n, LT * e)
{
//在线性顺序表L中删除第n个元素,并用e返回其值,位置为 1 ~ L->length
int i;
if (n < 1 || n > L->length + 1)
return ERROR;
*e = L->data[n - 1];
for (i = n - 1; i < L->length - 1; ++i) //删除位置元素之后的元素前移
L->data[i] = L->data[i + 1];
--L->length;
return OK;
}
Status Traverse_SqList(SqList L)
{
int i;
for (i = 0; i < L.length; ++i)
printf("%d ", L.data[i]);
}
int Locate_data(SqList L, LT e)
{
//在线性顺序表中返回e的位置,若找到返回位置(1 ~ L.length),否则返回-1
int i;
for (i = 0; i < L.length; ++i)
if (L.data[i] == e)
return i + 1;
return -1;
}
2.单链表
一种只有后继指针的线性单向链表,无法随机存取。
//名称:LinkList()
//功能:单链表
//说明:带头结点的单链表,头插法,表头数据存放链表长度
#include <stdio.h>
#include <stdlib.h>
#define OK 1
#define ERROR 0
typedef int Status;
//链表定义
typedef int LT; //ListElemType
typedef struct LNode {
LT data;
struct LNode * next;
} LNode, * LinkList;
//链表函数声明
void Init_LinkList(LinkList * L);
Status Get_LinkList(LinkList L, int n, LT * e);
Status Insert_LinkList(LinkList L, int n, LT e);
Status Delete_LinkList(LinkList L, int n, LT * e);
void Traverse_LinkList(LinkList L);
int main(void)
{
LT e;
LinkList L;
Init_LinkList(&L);
Traverse_LinkList(L);
Get_LinkList(L, 5, &e);
Insert_LinkList(L, 1, 9);
Insert_LinkList(L, 7, 9);
Traverse_LinkList(L);
Delete_LinkList(L, 2, &e);
printf("delete = %d\n", e);
Traverse_LinkList(L);
return 0;
}
void Init_LinkList(LinkList * L)
{
//使用头插法,逆序输入n个元素的值,建立带头结点的单链表L
int i, n;
LNode * p;
*L = (LNode *)malloc(sizeof(LNode)); //建立头指针
(*L)->next = NULL;
(*L)->data = 0; //头指针数据存放链表长度
printf("请输入链表元素的数量:");
scanf("%d", &n);
printf("请输入%d个链表元素:", n);
for (i = 0; i < n; ++i)
{
p = (LNode *)malloc(sizeof(LNode));
scanf("%d", &p->data);
p->next = (*L)->next;
(*L)->next = p;
++(*L)->data; //链表长度加一
}
}
Status Get_LinkList(LinkList L, int n, LT * e)
{
//获得单链表L中第n个位置的元素,并用e返回其值 (1≤n≤L->data)
int i;
LNode * p;
p = L;
if (n < 1 || n > L->data)
return ERROR;
for (i = 0; i < n; ++i, p = p->next); //p指向要查找的元素
*e = p->data;
printf("get = %d\n", *e);
return OK;
}
Status Insert_LinkList(LinkList L, int n, LT e)
{
//在单链表L中的第n个位置之前插入元素e ( 1≤n≤L->data + 1)
int i;
LNode * p, * s;
p = L;
s = (LNode *)malloc(sizeof(LNode));
s->data = e;
if (n < 1 || n > L->data + 1)
return ERROR;
for (i = 0; i < n - 1; ++i, p = p->next); //p指向要插入元素的前一个元素
s->next = p->next;
p->next = s;
++L->data;
return OK;
}
Status Delete_LinkList(LinkList L, int n, LT * e)
{
//在单链表L中删除第n个元素,并由e返回其值 (1≤n≤L->data)
int i;
LNode * p, * s;
p = L;
if (n < 1 || n > L->data)
return ERROR;
for (i = 0; i < n - 1; ++i, p = p->next); //p指向要删除元素的前一个元素
s = p->next; //s指向要删除元素
p->next = s->next;
*e = s->data;
free(s);
--L->data;
return OK;
}
void Traverse_LinkList(LinkList L)
{
int i;
LNode * p;
p = L->next;
for (i = 0; i < L->data; ++i, p = p->next)
printf("%d ", p->data);
printf("\n");
}
3.双链表
一种有前驱指针和后继指针的线性双向链表,无法随机存取。
//名称:DuLinkList()
//功能:双链表
//说明:带头结点的双链表,头插法,表头数据存放链表长度
#include <stdio.h>
#include <stdlib.h>
#define OK 1
#define ERROR 0
typedef int Status;
//链表定义
typedef int LT; //ListElemType
typedef struct DuLNode {
LT data;
struct DuLNode * prior, * next;
} DuLNode, * DuLinkList;
//链表操作
void Init_LinkList(DuLinkList * L);
Status Get_LinkList(DuLinkList L, int n, LT * e);
Status Insert_LinkList(DuLinkList L, int n, LT e);
Status Delete_LinkList(DuLinkList L, int n, LT * e);
void Traverse_LinkList(DuLinkList L);
int main(void)
{
LT e;
DuLinkList L;
Init_LinkList(&L);
Traverse_LinkList(L);
Get_LinkList(L, 5, &e);
Insert_LinkList(L, 1, 9);
Insert_LinkList(L, 7, 9);
Traverse_LinkList(L);
Delete_LinkList(L, 2, &e);
printf("delete = %d\n", e);
Traverse_LinkList(L);
return 0;
}
void Init_LinkList(DuLinkList * L)
{
//使用头插法,逆序输入n个元素的值,建立带头结点的双链表L
int i, n;
DuLNode * p;
*L = (DuLNode *)malloc(sizeof(DuLNode)); //建立头指针
(*L)->prior = (*L)->next = NULL;
(*L)->data = 0; //头指针数据存放链表长度
printf("请输入链表元素的数量:");
scanf("%d", &n);
printf("请输入%d个链表元素:", n);
for (i = 0; i < n; ++i)
{
p = (DuLNode *)malloc(sizeof(DuLNode));
scanf("%d", &p->data);
p->next = (*L)->next;
p->prior = (*L);
(*L)->next = p;
++(*L)->data; //链表长度加一
}
}
Status Get_LinkList(DuLinkList L, int n, LT * e)
{
//获得双链表L中第n个位置的元素,并用e返回其值
int i;
DuLNode * p;
p = L;
if (n < 1 || n > L->data)
return ERROR;
for (i = 0; i < n; ++i, p = p->next); //p指向要查找的元素
*e = p->data;
printf("get = %d\n", *e);
return OK;
}
Status Insert_LinkList(DuLinkList L, int n, LT e)
{
//在双链表L中的第n个位置之前插入元素e ( 1≤n ≤L->data + 1)
int i;
DuLNode * p, * s;
p = L;
s = (DuLNode *)malloc(sizeof(DuLNode));
s->data = e;
if (n < 1 || n > L->data + 1)
return ERROR;
for (i = 0; i < n - 1; ++i, p = p->next); //p指向要插入元素的前一个元素位置
s->prior = p;
s->next = p->next;
p->next = s;
p->next->prior = s;
++L->data;
return OK;
}
Status Delete_LinkList(DuLinkList L, int n, LT * e)
{
//在双链表L中删除第n个元素,并由e返回其值 (1≤n ≤L->data)
int i;
DuLNode * p, * s;
p = L;
if (n < 1 || n > L->data)
return ERROR;
for (i = 0; i < n - 1; ++i, p = p->next); //p指向删除元素的前一个元素
s = p->next; //s指向被删除元素
p->next = s->next;
s->next->prior = p;
*e = s->data;
free(s);
--L->data;
return OK;
}
void Traverse_LinkList(DuLinkList L)
{
int i;
DuLNode * p;
p = L->next;
for (i = 0; i < L->data; ++i, p = p->next)
printf("%d ", p->data);
printf("\n");
}