顺序存储:
一 数据结构
(1)数据存储 (顺序存储,链式存储,索引存储,哈希存储)
(2)数据间关系(逻辑关系:线性,非线性)
(3)数据操作 (增 删 改 查 排序)
二 线性关系-----顺序表 = 存放数据的空间[数组] + 当前数据的个数
1.数据结构
typedef int DATATYPE;
typedef struct
{
DATATYPE buf[MAX];//存放数据
int n;//记录当前数据的个数
}SeqList;
2.操作
SeqList *create_seqlist()
{
SeqList *L;
//分配内存
L = (SeqList *)malloc(sizeof(SeqList));
L->n = 0;
return L;
}
int insert_seqlist(SeqList *L,DATATYPE data)
{
//判断顺序表是否满
//如果满,则输出"The SeqList is full!",然会返回-1
//插入数据
L->buf[L->n] = data;
L->n ++;
return 0;
}
int printf_seqlist(SeqList *L)
{
...
}
int sort_seqlist(SeqList *L)
{
for(i = 0;i < L->n - 1;i ++)
{
for(j = 0;j < L->n - i - 1;j ++)
{
...
}
}
}
int find_seqlist(SeqList *L,DATATYPE data)
{
for(i = 0;i < L->n;i ++)
{
if(L->buf[i] == data)
break;
}
return (i + 1);
}
int insert_post_seqlist(SeqList *L,int post,DATATYPE data)
{
1.判断是否满 和 合法位置 [1,L->n],如果是非法位置,需要输出位置非法
2.指定位置插入的思想
[1]最后一个元素的下标 L->n - 1
[2]从后向前移动
for(i = L->n - 1;? ;i --)
{
L->buf[i + 1] = L->buf[i];
}
[3]插入
L->buf[?] = data;
[4]更新n的值
return 0;
}
int delete_data_seqlist(SeqList *L,DATATYPE data)
{
...
//提示:删除字符的选择题思路
}
int main()
{
SeqList *L;
L = create_seqlist();
//插入10个数据到顺序表
//输出顺序表
}
代码如下:
#include <stdio.h>
#include <stdlib.h>
#define MAX 10
typedef int DATATYPE;
typedef struct
{
DATATYPE data[MAX];
int n;
}SeqList;
SeqList *create_seqlist()
{
SeqList *L;
L = (SeqList *)malloc(sizeof(SeqList));
if(L == NULL){
printf("NO free memory!\n");
return NULL;
}
L->n = 0;
return L;
}
int insert_seqlist(SeqList *L,DATATYPE data)
{
if(L->n == MAX)
{
printf("The SeqList is full!\n");
return -1;
}
L->data[L->n] = data;
L->n ++;
return 0;
}
int printf_seqlist(SeqList *L)
{
int i = 0;
for(i = 0;i < L->n ;i ++)
{
printf("%d ",L->data[i]);
}
printf("\n");
return 0;
}
int insert_postion_seqlist(SeqList *L,int post,DATATYPE data)
{
int last;
//判断位置合法性[1,L->n]
if(!(post >= 1 && post <= L->n))
{
printf("The invaild postion : %d,must [1,%d]\n",post,L->n);
return -1;
}
//判断是否满
if(L->n == MAX)
{
printf("The SeqList is full\n");
return -1;
}
//从后向前移动数据
for(last = L->n - 1;last >= post - 1;last --)
{
L->data[last + 1] = L->data[last];
}
//插入数据
L->data[post - 1] = data;
//更新n的值
L->n ++;
return 0;
}
int delete_assign_data(SeqList *L,DATATYPE data)
{
int i,j;
//判断是否空
if(L->n == 0)
{
printf("The SeqList is empty!\n");
return -1;
}
//删除数据代碼
for(i = 0,j = 0;i < L->n;i ++)
{
if(L->data[i] != data)
{
L->data[j++] = L->data[i];
//j ++;
}
}
//判断要删除的元素是否存在
if(i == j){
printf("The delete data:%d is not exist!\n",data);
return -1;
}
//更新剩余数据的个数
L->n = j;
return 0;
}
int sort_seqlist(SeqList *L)
{
int i,j;
DATATYPE temp;
for(i = 0;i < L->n - 1;i ++)//需要排的次数
{
for(j = 0;j < L->n - 1 - i;j ++)//比较方法:前一个元素与后一个元素比较,每排序一次则少一个元素
{
if(L->data[j] > L->data[j+1])
{
temp = L->data[j];
L->data[j] = L->data[j+1];
L->data[j+1] = temp;
}
}
}
return 0;
}
int delete_repeat_data(SeqList *L)
{
int k;
int i,j;
for(i = 0;i < L->n ;i ++)
{
for(j = i + 1,k = i + 1;j < L->n;j ++)
{
if(L->data[j] != L->data[i])
{
L->data[k] = L->data[j];
k ++;
}
}
L->n = k;
}
return 0;
}
int main(int argc, const char *argv[])
{
int i = 0;
int a[] = {10,20,10,40,40,90,40,80,20};
SeqList *L;
L = create_seqlist();
if(L == NULL)
return -1;
for(i = 0;i < sizeof(a)/sizeof(a[0]);i ++)
{
insert_seqlist(L,a[i]);
}
printf_seqlist(L);
insert_postion_seqlist(L,3,100);
insert_postion_seqlist(L,5,100);
printf_seqlist(L);
delete_assign_data(L,100);
printf_seqlist(L);
delete_assign_data(L,101);
sort_seqlist(L);
printf_seqlist(L);
delete_repeat_data(L);
printf_seqlist(L);
return 0;
}
链式存储:
一 链式存储
[1]头节点记录第一个有效数据节点的首地址,本身不存放数据
[1]每个节点会记录下一个节点的地址
[2]尾节点是最后一个节点,它记录的地址为0(NULL)
1.节点的类型设计
typedef struct node
{
DATATYPE data;//存放数据
struct node *next;//记录下一个节点的地址
}LinkNode;
2.操作
[1]创建空链表
LinkNode *create_empty_linklist()
{
LinkNode *head;
head = (LinkNode *)malloc(sizeof(LinkNode));
head->next = NULL;
return head;
}
[2]插入新节点
<1>头插法(每次都是在头节点后面插入数据)
int insert_head_linklist(LinkNode *head,DATATYPE data)
{
分配一个节点
将data存放在新节点
新节点保存头的后一个节点地址
头节点保存新节点地址
}
<2>尾插法(每次都是在尾部节点后面插入数据)
int insert_tail_linklist(LinkNode *head,DATATYPE data)
[3]输出链表中的数据
int printf_linklist(LinkNode *head)
作业:
(1)实现一个链表的有序插入
int a[] = {10,3,4,15,6};
LinkNode *L = create_empty_linklist();
for(i = 0;i < sizeof(a)/sizeof(a[0]);i ++)
{
insert_order_linklist(L,a[i]);
}
printf_linklist(L);//3,4,6,10,15
(2)实现一个链表的逆置
代码如下:
#include <stdio.h>
#include <stdlib.h>
typedef int DATATYPE;
typedef struct node
{
DATATYPE data;
struct node *next;
}LinkNode;
LinkNode *create_linklist()
{
LinkNode *head;
head = (LinkNode *)malloc(sizeof(LinkNode));
if(head == NULL){
printf("No free memory!\n");
return NULL;
}
head->next = NULL;
return head;
}
int insert_head_linklist(LinkNode *head,DATATYPE data)
{
LinkNode *temp;
temp = (LinkNode *)malloc(sizeof(LinkNode));
temp->data = data;
//用新节点记录头的后一个节点
temp->next = head->next;
//用头节点记录新节点
head->next = temp;
return 0;
}
int insert_tail_linklist(LinkNode *head,DATATYPE data)
{
LinkNode *temp;
LinkNode *p = head;
//找到尾部节点
while(p->next != NULL)
{
p = p->next;
}
temp = (LinkNode *)malloc(sizeof(LinkNode));
temp->data = data;
temp->next = NULL;
//在尾部链接新节点
p->next = temp;
return 0;
}
int printf_linklist(LinkNode *head)
{
LinkNode *p;
for(p = head->next;p != NULL;p = p->next)
{
printf("%d ",p->data);
}
printf("\n");
return 0;
}
int delete_assign_linklist(LinkNode *head,DATATYPE data)
{
LinkNode *q = head;
LinkNode *p = head->next;
while(p)
{
if(p->data == data)
{
q->next = p->next;
free(p);
p = q->next;//重新让p在q的前面
}else{//不是要删除的元素,则p,q一起移动
p = p->next;
q = q->next;
}
}
return 0;
}
int find_mid_linklist(LinkNode *head)
{
LinkNode *p = head->next;//走两步
LinkNode *q = head->next;//走一步
while(1)
{
//走两步
p = p->next;
if(NULL == p)
break;
p = p->next;
if(p == NULL)
break;
//走一步
q = q->next;
}
printf("mid : %d\n",q->data);
return 0;
}
int insert_order_linklist(LinkNode *head,DATATYPE data)
{
LinkNode *temp;
LinkNode *q = head;
LinkNode *p = head->next;
while(p)
{
if(p->data > data){
break;
}else{
p = p->next;
q = q->next;
}
}
temp = (LinkNode *)malloc(sizeof(LinkNode));
temp->data = data;
temp->next = q->next;
q->next = temp;
return 0;
}
//算法:链表的插入排序
//思想:
// 1.断开头和后面的节点
// 2.有序插入后面的数据节点
int sort_linklist(LinkNode *head)
{
LinkNode *k;
LinkNode *t;
LinkNode *p,*q;
//断开
t = head->next;
head->next = NULL;
while(t != NULL)
{
q = head;
p = head->next;
while(p)
{
if(p->data > t->data)
{
break;
}else{
p = p->next;
q = q->next;
}
}
//k先保存t后面的节点
k = t->next;
t->next = q->next;
q->next = t;
//让t走到k的位置
t = k;
}
return 0;
}
int clean_linklist(LinkNode *head)
{
LinkNode *temp;
while(head != NULL)
{
//保存头面的节点
temp = head->next;
//删除头节点
free(head);
//修改head为temp
head = temp;
}
return 0;
}
int main(int argc, const char *argv[])
{
int i;
int a[] = {200,100,300};
LinkNode *L1 = create_linklist();
LinkNode *L2 = create_linklist();
LinkNode *L3 = create_linklist();
for(i = 0;i < sizeof(a)/sizeof(a[0]);i ++)
{
insert_head_linklist(L1,a[i]);
insert_tail_linklist(L2,a[i]);
insert_order_linklist(L3,a[i]);
}
// printf_linklist(L3);
printf_linklist(L2);
printf("sort L2:");
sort_linklist(L2);
printf_linklist(L2);
printf_linklist(L1);
delete_assign_linklist(L2,250);
printf_linklist(L2);
find_mid_linklist(L1);
find_mid_linklist(L2);
insert_order_linklist(L2,250);
insert_order_linklist(L2,250);
printf_linklist(L2);
return 0;
}