数据结构--静态链表


/*******线性表*********
* 线性表是最基本、最简单、也是最常用的一种数据结构。
* 线性表(linear list)是数据结构的一种,
* 一个线性表是n个具有相同特性的数据元素的有限序列
* 线性表以下四个特征:
* 1.集合中必存在唯一的一个“第一元素”。
* 2.集合中必存在唯一的一个 “最后元素” 。
* 3.除最后一个元素之外,均有唯一的后继(后件)。
* 4.除第一个元素之外,均有唯一的前驱(前件)。
* ************************/

/*******静态链表*********
* 由于动态链表在使用过程中需要进行创建结点等一系列操作,
* 消耗时间相对较长,因此一般在只比较速度的情况下,
* 使用数组创建静态链表能使速度更快。
* 优点:增、删操作不需要大量移动元素
* 缺点:不能随机存取,只能从头节点开始,容量固定,不可改变。
* 适用:数据元素固定不变的场景(操作系统的文件分配表FAT)
******************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "phoneNote.h"



#define BUFF_SZIE 100
#define MAX_SIZE 1*1024
typedef PhoneNote elemType;

/*******线性链表(单链表)*********
* 由于动态链表在使用过程中需要进行创建结点等一系列操作,
* 消耗时间相对较长,因此一般在只比较速度的情况下,
* 使用数组创建静态链表能使速度更快。
******************/
/// @brief 静态单链表
typedef struct {
elemType data;
int cur;
}slinkNode,slinkList[MAX_SIZE];

typedef slinkList List;

#define m_data "slinkList.data"
#define CAPTION "slinkList"

#define exPrint phoneNote_printw
#define exCreat phoneNote_creat
#define exSearch phoneNote_search
#define exModify phoneNote_modify
#define exCmp phoneNote_cmp
#define exSwp phoneNote_swap

#define m_print(list) showslinkList(list,exPrint)
#define m_load(list) loadslinkList(list,m_data,exCreat)
#define m_save(list) saveslinkList(list,m_data)
#define m_search(list,key,value,del) searchslinkList(list,key,value,phoneNote_search,del)
#define m_insert(list,item,pos) insertslinkList(list,item,pos)
#define m_delete(list,pos) deleteslinkList(list,pos)
#define m_clear(list) clearslinkList(list)
#define m_destroy(list) destroyslinkList(list)
#define m_lenght(list) getLenghtslinkList(list)
#define m_modify(list,pos) modifyslinkList(list,pos,exModify)
#define m_merge(la,lb) mergeslinkList(la,lb)
#define m_sort(list,key,desc) sortslinkList(list,key,desc,exCmp)
#define m_resver(list) resverslinkList(list)
#define m_inputelem() phoneNote_scanf()
#define m_init(list) initslinkList(list)

List* initslinkList(List* list)
{
if(list==NULL)return NULL;
memset(list,0,sizeof(List));
for (int i=1; i < MAX_SIZE-1; i++)(*list+i)->cur=i+1;
(*list)->cur=-1;
return list;
}

List* createslinkList()
{
return initslinkList((List*)calloc(MAX_SIZE,sizeof(List)));

}
//申请静态链表节点
int mallocslinkList(List *list,int size)
{
int i=(*list+1)->cur;
//如果备用区中还有可用的空间那么就进行分配
//更改备用区头指针的指向
if((*list+1)->cur) (*list+1)->cur=(*list+i)->cur;
return i;
}

int freeslinkList(List *list,int index)
{
(*list+index)->cur=(*list+1)->cur;
(*list+1)->cur=index;
}
int getLenghtslinkList(List* list)
{
int count=0,index=0;
while((index=(*list+index)->cur)>-1)count++;
return count;
}
int getindexslinkList(List* list,int pos)
{
int index=0,k=0, len;
if(!list){return -2;}
len=getLenghtslinkList(list);
if(pos<0 || pos>len-1){return -1;}
while(((*list+index)->cur)>-1 && k<=pos &&k<len)
{index=(*list+index)->cur;k++;}
return index;
}
int swapslinkLinkS(List* list,int pa,int pb)
{
int index=0,temp=0,a=0,b=0,c=0,j=0;
if(pa>pb) {pa=pa+pb;pb=pa-pb;pa=pa-pb;}
if(pa==pb || pa<0 || pb<0 )return 0;
//if(pa==pb || pa<0 || pb<0 )return 0;
j=0;while(((*list+a)->cur)>-1 && j<=pa-1){j++;a=(*list+a)->cur;}
j=0;while(((*list+c)->cur)>-1 && j<=pb){j++;c=(*list+c)->cur;}
if((*list)->cur==a){a=0;}
b=(*list+a)->cur;
(*list+a)->cur=(*list+b)->cur;
(*list+b)->cur=(*list+c)->cur;
(*list+c)->cur=b;
}
int _quickSortlinkList(List * list,int lefte,int righte,int desc,const char*key,
int (*elemCmp)(elemType *p1,elemType* p2, const char* key))
{
if( lefte>=righte )return 0;
int i=lefte,j=righte;
elemType* tmp=&((*list+lefte)->data);

while(i<j)
{
// while (((desc && tmp<(*arr+i).dat)||(!desc && tmp>arr[i]))&&(i<righte)) i++;
while (((desc && elemCmp(tmp,&((*list+i)->data),key)<0)||(!desc && elemCmp(tmp,&((*list+i)->data),key)>0))&&(i<righte)) i++;
// while (((desc && tmp>arr[j])||(!desc && tmp<arr[j]))&&(j>=i)) j--;
while (((desc && elemCmp(tmp,&((*list+j)->data),key)>0)||(!desc && elemCmp(tmp,&((*list+j)->data),key)<0))&&(j>=i)) j--;
if(i<j)
{//swap(&arr[i],&arr[j]);
swapslinkLinkS(list,i,j);
// showArrary(arr,ARR_MAX_SIZE);
}
}
//if((desc && tmp>arr[j])||(!desc && tmp>arr[j]))
if((desc && elemCmp(tmp,&((*list+j)->data),key)>0)||(!desc && elemCmp(tmp,&((*list+j)->data),key)>0))
{ //swap(&arr[lefte],&arr[j]);
swapslinkLinkS(list,lefte,j);
//showArrary(arr,ARR_MAX_SIZE);
}

_quickSortlinkList(list,lefte,j-1,desc,key,elemCmp);
_quickSortlinkList(list,j+1,righte,desc,key,elemCmp);


}
List *quickSortlinkList(List *list, const char* key, int desc,
int (*elemCmp)(elemType *p1,elemType* p2, const char* key))
{
int length=getLenghtslinkList(list);
_quickSortlinkList(list,0,length-1,desc,key,elemCmp);
return list;
}
int insertslinkList(List *list, elemType *item, int pos)
{
int index=0;
int len=getLenghtslinkList(list);
if(pos<0 || pos>len){return 1;}
if(list==NULL || item==NULL) return 2;
if(pos<0 || pos >MAX_SIZE-1)return 3;
if(!(index=mallocslinkList(list,0))) return 4;
memcpy(&((*list+index)->data),item,sizeof(elemType));
(*list+index)->cur=(*list)->cur;
(*list)->cur=index;
swapslinkLinkS(list,0,pos);
return 0;


}
int deleteslinkList(List* list, int pos)
{ int index=0,temp=0,a=0,b=0,c=0,j=0,len=0;
len=getLenghtslinkList(list);
if(pos<0 || pos>len-1){return 1;}
j=0;while(((*list+a)->cur)>-1 && j<=pos-1 &&j<len-1){j++;a=(*list+a)->cur;}
b=(*list+a)->cur;
c=(*list+b)->cur;
(*list+a)->cur=c;
freeslinkList(list,b);
return 0;
}
int modifyslinkList(List* list, int pos, int (*elemModify)(elemType *p))
{ int index=0;
if((index=getindexslinkList(list,pos))<0)return index;
return elemModify(&((*list+index)->data));
}
List* searchslinkList(List* list, const char *key, const char *value, elemType *(*elemSearch)(elemType *p, const char *key, const char *value), int del)
{
int index=0,j=0;
List *result=createslinkList();
while((index=(*list+index)->cur)>-1)
{
if(elemSearch(&((*list+index)->data),key,value))
{insertslinkList(result,&((*list+index)->data),0);
if(del==1)(deleteslinkList(list,index));}
}
return result;

}

int showslinkList(List* list, void (*_print)(elemType *p))
{ if(!list){printf("error object is NULL\n");return -1;}
printf("\n--------- Show element ------------------\n");

int index=(*list)->cur;
while(index>-1)
{
_print(&((*list+index)->data));
index=(*list+index)->cur;
}
printf("----------- Total: %d --------------------\n\n",getLenghtslinkList(list));
return 0;
}

int clearslinkList(List* list)
{
initslinkList(list);
return 0;
}
int destroyslinkList(List** list)
{
free((*list));
(*list)=NULL;
return 0;
}
int loadslinkList(List* list, const char *file, elemType *(*_creatItem)())
{
FILE* fp = fopen(file, "rb");
elemType* item=NULL;
if(list==NULL)
{ printf("sequence list is null\n");
return -1;}
if(fp==NULL){
printf("Failed to open file\n");
return -2;
}
item=phoneNote_creat();
if(item==NULL){
printf("Failed to Create empty elemType\n");
return -3;}
int rel=0;
while(fread(item,sizeof(elemType),1,fp))
{
if(insertslinkList(list,item,0))return 0;
}
fclose(fp);
return 0;
}
int saveslinkList(List* list, const char *file)
{
FILE* fp = fopen(file, "w"); int index=0;
if(list==NULL) {printf("sequence list is null\n");return -1;}
if(fp==NULL){ printf("Failed to open file\n"); return -2; }
while((index=(*list+index)->cur)>0)
{
fwrite(&((*list+index)->data),sizeof(elemType),1,fp);

}
fclose(fp);
return 0;
/******
* hexdump -C slinkList.data # 查看二进制文件 -C 显示对应字节的ASCII码。
* od -x linkList.data # 查看二进制文件
* vim -b slinkList.data # 打开二进制文件
* :%!xxd -c 12 # 将内容转化为16进制,每行显示12个字节(默认:16个字节)
* :%!xxd -r # 编辑完成后,转换回文本格式,保存退出。
*****/
}

/****/
List* mergeslinkList(List* la,List* lb)
{
if(!la)return NULL;
if(!lb)return la;
int index=0;
while((index=(*lb+index)->cur)>-1)
{insertslinkList(la,&((*lb+index)->data),getLenghtslinkList(la));}
return la;
}
int sortslinkList(List* list, const char* key, int desc,int (*elemCmp)(elemType *p1,elemType* p2, const char* key))
{
int s=(*list)->cur;
int q=(*list+s)->cur;
int p=0;
(*list+s)->cur=-1;
q=(*list+q)->cur;
while(q>-1)
{
s=q;
q=(*list+q)->cur;
p=(*list)->cur;
switch (desc)
{
case 0:
while((*list+p)->cur>-1 && elemCmp(&((*list+(*list+p)->cur)->data),&((*list+s)->data),key)<=0){p=(*list+p)->cur;}
break;
case 1:
//while(p->next && elemCmp(&(p->next->data),&(s->data),key)>0){p=p->next;}
while((*list+p)->cur>-1 && elemCmp(&((*list+(*list+p)->cur)->data),&((*list+s)->data),key)>0){p=(*list+p)->cur;}
break;
default:
while((*list+p)->cur>-1 && elemCmp(&((*list+(*list+p)->cur)->data),&((*list+s)->data),key)<=0){p=(*list+p)->cur;}
break;
}
// while(p->next && elemCmp(&(p->next->data),&(s->data),key)<=0){p=p->next;}
// while(p->next && elemCmp(&(p->next->data),&(s->data),key)>0){p=p->next;}
//s->next=p->next;p->next=s;
if(p==(*list)->cur)
{
(*list)->cur=s;
(*list+s)->cur=p;
}
else
{
(*list+s)->cur=(*list+p)->cur;
(*list+p)->cur=s;}
}
return 0;


}

int resverslinkList(List* list)
{
if(!list && (*list)->cur<=-1 && (*list+(*list)->cur)->cur<=-1) return 0;
int s=0,q=0 ,p=0;
s=(*list)->cur;
q=(*list+s)->cur;
(*list+s)->cur=-1;
while(q>-1)
{
s=q;
q=(*list+q)->cur;
p=(*list)->cur;
(*list)->cur=s;
(*list+s)->cur=p;

}
return 0;

}
void printslinkListError(const char * contet,int errorCode)
{
printf("\e[1;31m %s failed. Error code[%d]\n\e[0m",contet,errorCode);
}

//int slinkListTest(int argc, char const **argv)
int main(int argc, char const **argv)
{


List* list=NULL;
List* newlist=NULL;
int pos=0,rel=0,errorCode=0;
elemType *item =NULL;
int select = 1;
char a=0x00;

list=createslinkList();

while (select)
{
char cmd[100]={0};
char key[100]={0};
char value[100]={0};

printf("\n******\t%s\t******************\n",CAPTION);
printf("* [1] insert_pos [2] delete_pos *\n");
printf("* [3] show_list [4] search *\n");
printf("* [5] sort [6] resver *\n");
printf("* [7] clear [8] merge *\n");
printf("* [9] reduce [10] delete_val *\n");
printf("* [11] load [12] save *\n");
printf("* [13] modify *\n");
printf("* [0] quit *\n");
printf("************************************\n");
printf("\e[1;32mplease Enter :>\e[0m");
scanf("%d", &select);

switch (select)
{

case 0:
printf("\e[1;31m %s goodbye!\n\e[0m",CAPTION);
m_destroy(&list); return 0;/*exit(0);*/
break;
case 1://insert_pos
pos=m_lenght(list);
printf("Please enter the insertion position [%d] ",pos);
scanf("%c",cmd); scanf("%[^\n]",cmd);
if((cmd[0]>=0x30 && cmd[0]<=0x39)||cmd[0]==0x2d )
{pos=atoi(cmd);
if(pos<0 || pos>getLenghtslinkList(list))
{printf("Insert position out of bounds\n");break;}
}
if((item=m_inputelem())==NULL)
{ printf("insert failed,Element is empty\n");break; }
if(!(errorCode=m_insert(list,item,pos))) {m_print(list);}
else printslinkListError("Insert position out of bounds ",errorCode);
break;
case 2://del_pos
pos=m_lenght(list)-1;
printf("Please enter the insertion position [%d] ",pos);
scanf("%c",cmd); scanf("%[^\n]",cmd);
if((cmd[0]>=0x30 && cmd[0]<=0x39)||cmd[0]==0x2d )
{pos=atoi(cmd);
if(pos<0 || pos>getLenghtslinkList(list)-1)
{printf("Delete position out of bounds\n");break;}
}
if(!(errorCode=m_delete(list,pos))) {m_print(list);}
else printslinkListError("delete ",errorCode);
break;
case 3: //show_list
m_print(list);
break;
case 4: //search
printf("Please enter the search key ");scanf("%s",key);
printf("Please enter the search value ");scanf("%s",value);
m_print(m_search(list,key,value,0));
break;
case 5: //sort
printf("Please enter the sort key [name] ");scanf("%c",key); scanf("%[^\n]",key);
if(key[0]<0x30) strncpy(key,"name",strlen("name"));
printf("Please enter the sort key < 0 :abs ,1: desc > [0] ");scanf("%c",cmd); scanf("%[^\n]",cmd);
pos=0;if(cmd[0]>=0x30) {pos=atoi(cmd);}
m_sort(list,key,pos);
m_print(list);
break;
case 6: //resver
m_resver(list);
m_print(list);
break;
case 7: //clear
m_clear(list);
m_print(list);
break;
case 8: //merge
newlist=createslinkList();
m_load(newlist) ;
m_print(m_merge(list,newlist));
break;
case 9: //reduce
printf("\033[32m Do not reduce \033[0m\n");
break;
case 10: //delete_val
printf("Please enter the delete key ");scanf("%s",key);
printf("Please enter the delete value ");scanf("%s",value);
m_print(m_search(list,key,value,1));
m_print(list);
break;
case 11: //load
m_clear(list);
if(!(errorCode=m_load(list))) m_print(list);
else printslinkListError("load ",errorCode);
break;
case 12: //save
if(!(errorCode=m_save(list)))
printf("\e[1;31m save successful \n\e[0m");
break;
case 13: //modify
pos=m_lenght(list)-1;
printf("Please enter the insertion position [%d] ",pos);
scanf("%c",cmd); scanf("%[^\n]",cmd);
if(cmd[0]>=0x30 && cmd[0]<=0x39 ) {pos=atoi(cmd);}
m_modify(list,pos);
m_print(list);
break;

default: //please re-enter
printf("\033[32m Wrong selection, please re-enter \033[0m\n");
break;
}

printf("press any key to continue...... ");
/*************************
* scanf()中的%c 不能正常输入的问题
* 在*%c前面加一个空格,将存于缓冲区中的回车符读入
* char a;
* scanf("%c%c",&a,&a);
*************************/
scanf("%c%c",&a,&a);
}
return 0;

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值