线性表一
- 开辟内存空间连续
- 长度固定(#define N 10)
- 插入和删除比较复杂,查询和修改比较简单。
seqlist.h N从1开始
typedef int datatype;
typedef struct
{
datatype data[N];
int last;
}seqlist_t;
//创建空的顺序表
seqlist_t *createEmptySeqList(void);
//2.指定位置插入数据
int insertPostSeqList(seqlist_t *p,int post,datatype data);
//3.判断表是否满
int isFullSeqlist(seqlist_t *p);
//4.指定位置删除数据
int delectPostSeqlist(seqlist_t *p,int post);
//5.判断表是否为空
int isEmptySeqlist(seqlist_t * p);
//6.遍历顺序表
void showSeqlist(seqlist_t *p);
seqlist.c
//1.创建空的顺序表
seqlist_t *createEmptySeqList(void)
{
seqlist_t *p;
p=(seqlist_t *)malloc(sizeof(seqlist_t));
if(NULL == p)
{
printf("createEmptySeqList err.\n");
return NULL;
}
p->last=-1;//空的
return p;
}
int isFullSeqlist(seqlist_t *p)
{return p->last==max-1;}
int isEmptySeqlist(seqlist_t *p)
{return p->last==-1;}
int insertPostSeqList(seq *p,int post,int x)
{
//先判断位置是否合法
if(post<0 || post>=last+1 ||full(p)) return -1;
//此位置的后面所有元素均向后移动一个元素,把前一项的值赋给后一项
for(i=last+1;i>post;i--)
{
p->data[i]=p->data[i-1];
}
data[post]=x;
p->last++;
}
int delectPostSeqlist(seqlist_t *p,int post);
{
//判断位置是否合法
if(post<0 || post>last ||empty(q))
//此位置及后面所有元素均向前移动一个元素,把后一项的值赋给前一项
for(j=post;j<last;j++)
{
p->data[j]=p->data[j+1];
}
p->last--;
}
-
链表
链表的特点:
- 开辟内存空间不连续,通过地址连接到一起
- 长度不固定
- 插入和删除比较简单,不需要移动节点,查询和修改比较复杂。
单链表
有头节点的 下面代码采用第二个节点的post=0
无头结点的: 第一个节点就开始存放数据
typedef int datatype; typedef struct node_t { datatype data;//数据域 struct node_t *next;//指针域 }link_t //1.创建一个空的有头单向链表 link_t *createLinkList(void); //2.链表指定位置插入数据 int insertPostLinkList(link_t *p,int post,datatype data); //3.计算链表的长度。 int lengthLinkList(link_t *p); //4.遍历链表 void showLinkList(link_t *p); //5.链表指定位置删除数据 int delectPostLinkList(link_t *p,int post); //6.判断链表是否为空 int isEmptyLink(link_t *p); //7.查询指定数据在链表的位置 int searchDataLink(link_t *p,datatype data); //8.链表的转置 1 2 3 4 5 5 4 3 2 1 //9.清空链表 //10.销毁链表
linklist.c
//1.创建一个空的有头单向链表 link_t *createLinkList(void) { link_t *p=(link_t *)malloc(sizeof(link_t)); if(NULL == p) { printf("createLinkList error.\n"); return NULL; } //数据域无效,指针域有效 p->next=NULL; return p; } //2.链表指定位置插入数据 int insertPostLinkList(link_t *p,int post,datatype data) { int i; link_t *pnew=NULL; //1.容错处理(判断位置 ) post<0 || post>len if(post < 0 || post > lengthLinkList(p)) { printf("insertPostLinkList error.\n"); return -1; } //2.定义一个指针保存新建节点地址 pnew=(link_t *)malloc(sizeof(link_t)); if(pnew == NULL) { printf("malloc new node error.\n"); return -1; } //3.初始化新建节点 pnew->data=data; pnew->next=NULL; //4.移动头指针到插入节点的前一个节点 for(i=0;i<post;i++) { p=p->next; } //5.插入:先连后边,再断开前边 pnew->next=p->next; p->next=pnew; return 0; } //3.计算链表的长度。 int lengthLinkList(link_t *p) { int len=0; while(p->next != NULL) { p=p->next; len++; } return len; } //4.遍历链表 void showLinkList(link_t *p) { while(p->next != NULL) { p=p->next; printf("%d ",p->data); } putchar(10); }
//5.链表指定位置删除数据
int delectPostLinkList(link_t *p,int post)
{
int i;
link_t *pdel=NULL;
//1.容错处理(判断位置)
if( post<0 || post>=lengthLinkList(p))
{
printf("delectPostLinkList error.\n");
return -1;
}
//2.将头指针移动到删除节点的前一个位置
for(i=0;i<post;i++)
{
p=p->next;
}
//3.定义一个指针(pdel)保存删除节点的地址
pdel=p->next;
//4.跨过删除节点
p->next=pdel->next;
//5.释放删除节点空间
free(pdel);
pdel=NULL;
return 0;
}
//6.判断链表是否为空
int isEmptyLink(link_t *p)
{
return p->next == NULL;//1:空 0:非空
}
//7.查询链表指定位置的数据
datatype searchPostLink(link_t *p,int post)
{
//容错处理
if(post < 0 || post >= lengthLinkList(p))
{
printf("searchPostLink error.\n");
return -1;
}
int i;
for(i=0;i<=post;i++)
{
p=p->next;
}
return p->data;
}
//8.查询指定数据在链表的位置
int searchDataLink(link_t *p,datatype data)
{
if(isEmptyLink(p))
{
printf("isEmptyLink error.\n");
return -1;
}
int post=0;
while(p->next != NULL)
{
p=p->next;
if(p->data == data)
return post;
post++;
}
return -1;
}
//9.修改链表中指定的数据
int chengeDataLink(link_t *p,datatype old,datatype new)
{
if(isEmptyLink(p))
{
printf("isEmptyLink error.\n");
return -1;
}
while(p->next != NULL)
{
p=p->next;
if(p->data == old)
p->data=new;
}
return 0;
}
//10.链表的转置 1 2 3 4 5 5 4 3 2 1
void reverseLinkList(link_t *p)
{
link_t *pt=p->next;;
link_t *pa=p->next;
p->next=NULL;
//循环遍历无头单向链表
while(pt != NULL)
{
pt=pt->next;
//头插法
pa->next=p->next;
p->next=pa;
pa=pt;
}
}
//11.清空链表
void clearLinkList(link_t *p)
{
link_t *pdel=NULL;//保存删除节点的地址
while(p->next != NULL)
{
pdel=p->next;
//跨过删除就节点
p->next=pdel->next;
//释放节点空间
free(pdel);
pdel=NULL;
}
}
//12.销毁链表
void destroyLink(link_t **sp)
{
if(!isEmptyLink(*sp))
{
clearLinkList(*sp);
}
free(*sp);
*sp=NULL;
}
3.递增有序的链表A 1 3 5 7 9 10
递增有序的链表B 2 4 5 8 11 15
新链表:1 2 3 4 5 5 7 8 9 10 11 15
将链表A和B合并为A,形成一个递增有序的新链表
void combinAB(link_t *pa,link_t *pb)
{
link_t *pt=pa->next;
pa->next=NULL;
pb=pb->next;
while(pt != NULL && pb != NULL)
{
if(pt->data > pb->data)
{
pa->next=pb;
pb=pb->next;
}else
{
pa->next=pt;
pt=pt->next;
}
pa=pa->next;
pa->next=NULL;
}
if(pt != NULL)
{
a->next=pt;
}else if(pb != NULL)
pa->next=pb;
}