二、顺序表与链表
(一)线性结构
1.线性结构:逻辑上是线性关系,元素与元素之间存在先后关系
2.物理结构
(1)顺序存储:元素存储位置连续
(2)链式存储:元素存储位置不连续,但逻辑上连续
(二)顺序表
1.顺序表的插入
(1)注意越界与表满
(2)数据后移,从最后一个元素后移,防止元素覆盖
2.顺序表的删除
(1)注意越界与表空
(2)数据前移,插入元素后一个元素前移,元素覆盖
3.代码实现
#include <stdio.h>
#include <stdlib.h>
//顺序表结构定义
#define Elem int
typedef struct Sqlist {
Elem* data;
int capacity;
int length;
}sqlist;
//顺序表初始化
int init(sqlist* s,int capacity)
{
int flag = 0;
s->data = (Elem*)malloc(sizeof(Elem)*capacity);
if(s->data == NULL)
flag = -1;
s->capacity = capacity;
s->length = 0;
return flag;
}
//顺序表插入元素
int insert(sqlist* s,Elem data,int index)
{
int flag = 0;
if(s->length == s->capacity || index < 0 || index > s->length)
flag = -1;
else
{
for(int i = s->length;i > index;i--)
s->data[i] = s->data[i-1];
s->data[index] = data;
s->length++;
}
return flag;
}
//顺序表删除元素
int delete(sqlist* s,int index)
{
int flag = 0;
if(index < 0 || index >= s->length || s->length == 0)
flag = -1;
else
{
for(int i = index;i < s->length;i++)
s->data[i] = s->data[i+1];
s->length--;
}
return flag;
}
//顺序表打印
void print(sqlist s)
{
for(int i = 0;i < s.length;i++)
printf("%d ",s.data[i]);
}
int main()
{
/* Write C code in this online editor and run it. */
sqlist s;
init(&s,5);
for(int i = 0;i < 6;i++)
insert(&s,i,i);
for(int i = 0;i < 5;i++)
delete(&s,i);
print(s);
return 0;
}
(三)链表
1.节点的查找
(1)查找节点不越界
2.节点的插入
(1)插入节点指向插入原位置节点
(2)插入节点位置前一个节点指向插入节点
3.节点的删除
(1)被删除节点的前一个节点指向被删除节点的后一个节点
(2)释放被删除节点空间
4.代码实现
#include <stdio.h>
#include <stdlib.h>
//链表结构定义
#define Elem int
typedef struct Linklist {
Elem data;
struct Linklist* next;
}linklist;
//创建新节点
linklist* createNode(Elem data)
{
linklist* node = (linklist*)malloc(sizeof(linklist));
node->data = data;
node->next = NULL;
return node;
}
//找到节点
linklist* findNode(linklist* head,int index)
{
int i = 0;
while(i < index - 1 && head)
{
head = head->next;
i++;
}
return head;
}
//链表插入节点
int insert(linklist* *phead,Elem data,int index)
{
int flag = 0;
if(index <= 0)
return -1;
linklist* node = createNode(data);
if(node == NULL)
return -1;
//头插
if(index == 1)
{
node->next = *phead;
(*phead) = node;
}
//其他位置插入
else
{
linklist* temp;
//找点节点的前一个节点
temp = findNode(*phead,index - 1);
if(temp)
{
//插入节点指向插入位置节点
node->next = temp->next;
//插入位置节点前一个节点指向插入节点
temp->next = node;
}
else
flag = -1;
}
return flag;
}
//链表删除节点
int delete(linklist* *phead,int index)
{
if(index <= 0)
return -1;
int flag = 0;
linklist* temp = *phead;
linklist* temp1;
//删除头节点
if(index == 1)
{
*phead = (*phead)->next;
free(temp);
}
else
{
//找到被删除节点
temp = findNode(*phead,index);
if(temp)
{
//找到被删除节点前一个节点
temp1 = findNode(*phead,index - 1);
//被删除节点前一个节点指向被删除节点后一个节点
temp1->next = temp->next;
free(temp);
}
else
flag = -1;
}
return flag;
}
//链表元素个数
int length(linklist* head)
{
int flag = 0;
while(head)
{
head = head->next;
flag++;
}
return flag;
}
//链表打印
void print(linklist* head)
{
while(head)
{
printf("%d",head->data);
head = head->next;
}
}
int main()
{
/* Write C code in this online editor and run it. */
linklist* head;
head = createNode(0);
insert(&head,1,2);
insert(&head,2,1);
insert(&head,3,2);
insert(&head,4,6);
delete(&head,2);
delete(&head,1);
delete(&head,3);
print(head);
printf("%d",length(head));
return 0;
}