顺序表和链表 优缺点
存储方式:
顺序表是一段连续的存储单元
链表是逻辑结构连续物理结构(在内存中的表现形式)不连续
时间性能,
查找顺序表O(1):下标直接查找
链表 O(n):从头指针往后遍历才能找到
插入和删除:
顺序表 O(n):需要整体元素移动后插入
链表 O(1):只需改指定位置指针指向即可。
空间性能
顺序表 需要预先分配空间,大小固定
链表, 不需要预先分配,大小可变,动态分配
循环链表
简单的来说,就是将原来单链表中最有一个元素的next指针指向第一个元素或头结点,链表就成了一个环,头尾相连,就成了循环链表。circultlar linker list。
双向链表:
如图:每个节点都包含三部分,数据,指向下个节点的指针,指向上个节点的指针。
Makefile:工程管理工具。
预处理、编译、汇编生产obj、链接
a.out:main.c ./doubleLinklist.c
gcc main.c doubleLinklist.c
Clean:
rm a.out.
保存后按make命令默认走第一条规则生成a.out
按make clean清除a.out
#代表源文件
SRC += main.c
SRC +=doulink.c
DST = app
CC = gcc
FLAG = -g
LIB=-lm
$(DST):$(SRC)
$(CC) $(SRC) $(FLAG) $(LIB) -o $(DST)
clean
rm $(DST)
指定文件:make -f makefile2
今天写了双向链表相关操作的函数:
#include "doulink.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct DouLinkList* CreateDouLinkList()//创建双向链表
{
struct DouLinkList* dl = (struct DouLinkList*) malloc(sizeof(struct DouLinkList));
if(NULL == dl)
{
fprintf(stderr,"CreateDouLinkList malloc\n");
return NULL;
}
dl->head = NULL;
dl->clen = 0;
return dl;
}
int InsertHeadDouLinkList(struct DouLinkList* dl, struct DATATYPE* data)//双向链表头查
{
struct DouNode * newnode = (struct DouNode*)malloc(sizeof(struct DouNode));
if(NULL == newnode)
{
fprintf(stderr,"inserthead malloc\n");
return 1;
}
memcpy(&newnode->data,data,sizeof(struct DATATYPE));
newnode->next = NULL;
newnode->prev = NULL;
newnode->next = dl->head;
if(dl->head)
{
dl->head->prev = newnode;
}
dl->head = newnode;
dl->clen++;
return 0;
}
int ShowDouLinkList(struct DouLinkList* dl,DIR dir)//双向链表遍历
{
struct DouNode* tmp = dl->head;
if( FORWADR==dir)
{
while(tmp)
{
printf("%s %c %d %d\n",tmp->data.name,tmp->data.sex,tmp->data.age,tmp->data.score);
tmp=tmp->next;
}
}
else if(BACKWADR == dir)
{
while(tmp->next)
{
tmp=tmp->next;
} // end node
while(tmp)
{
printf("%s %c %d %d\n",tmp->data.name,tmp->data.sex,tmp->data.age,tmp->data.score);
tmp=tmp->prev;
}
}
return 0;
}
int InsertTailDouLinkList(struct DouLinkList*dl,struct DATATYPE*data)//双向链表尾插
{
if(IsEmptyDouLinkList(dl))
{
return InsertHeadDouLinkList(dl,data);
}
else
{
struct DouNode* tmp = dl->head ;
while(tmp->next)
{
tmp= tmp->next;
}
struct DouNode* newnode = (struct DouNode*)malloc(sizeof(struct DouNode));
if(NULL == newnode)
{
fprintf(stderr,"InsertTailDouLinkList malloc\n");
return 1;
}
//初始化节点
memcpy(&newnode->data,data,sizeof(struct DATATYPE));
newnode->next = NULL;
newnode->prev = NULL;
// 连接链表
newnode->prev = tmp;
tmp->next = newnode;
dl->clen++;
}
return 0;
}
int InsertPosDouLinkList(struct DouLinkList*dl,struct DATATYPE*data,int pos)//双向链表指定位置插入元素
{
int len = GetSizeDouLinkList(dl);
if(pos<0 || pos>len)
{
return 1;
}
if(0 == pos)
{
return InsertHeadDouLinkList(dl,data);
}
else if(pos == len)
{
return InsertTailDouLinkList(dl,data);
}
else
{
struct DouNode* tmp = dl->head;
int i = 0 ;
for(i = 0 ;i<pos;++i)
{
tmp=tmp->next;
}
struct DouNode* newnode = (struct DouNode*)malloc(sizeof(struct DouNode));
if(NULL == newnode)
{
fprintf(stderr,"InsertposDouLinkList malloc\n");
return 1;
}
memcpy(&newnode->data , data,sizeof(struct DATATYPE));
newnode->next = NULL;
newnode->prev = NULL;
newnode->next = tmp;
newnode->prev = tmp->prev;
tmp->prev = newnode;
newnode->prev->next = newnode;
dl->clen++;
}
return 0;
}
int IsEmptyDouLinkList(struct DouLinkList*dl)//双向链表是否为空
{
return 0 == dl->clen;
}
int GetSizeDouLinkList(struct DouLinkList*dl)//双向链表长度获取
{
return dl->clen;
}
struct DouNode* FindDouLinkList(struct DouLinkList* dl,char *name)//查找元素
{
if(IsEmptyDouLinkList(dl))
{
return NULL;
}
struct DouNode* tmp = dl->head;
int len = GetSizeDouLinkList(dl);
int i = 0 ;
for(i = 0 ;i< len; ++i)
{
if(0 == strcmp(tmp->data.name,name))
{
return tmp;
}
tmp= tmp->next;
}
return NULL;
}
int ModifyDouLinkList(struct DouLinkList* dl,char *name,struct DATATYPE* data)//修改元素
{
struct DouNode* ret = FindDouLinkList(dl,name);
if(NULL == ret)
{
return 1;
}
memcpy(&ret->data,data,sizeof(struct DATATYPE));
return 0;
}