顺序表(向量表、数组)
逻辑结构:一对一
存储结构:顺序存储
#define SIZE 5
typedef int data_t;
//描述一个顺序表的结构体
typedef struct List
{
data_t data[SIZE]; //可以为任意数据类型此处为int
int count; //已经存入了count个元素
}List;
//在下标为iOffset处增加一个元素
int iOffset=1;
for(i=count;i>iOffset;i--)
{
data[i] = data[i-1];
}
data[iOffset] = tData;
count++;
// 将下标为iOffset处的元素删除
iOffset = 1;
for(i=iOffset;i<count-1;i++)
{
data[i] = data[i+1];
}
count--;
动态扩容顺序表
define SIZE 10
typedef int data_t;
//定义一个动态扩容数组结构体
typedef struct List
{
data_t *pData; //指向一个申请的数组,大小不够了申请更大的,把原来的释放掉
int size; //申请的空间大小
int count; //已经存入的元素个数
}List;
/*
*功能:创建顺序表并初始化
*参数:无
*返回值:失败NULL,成功:顺序表的首地址
*/
List *creatList()
{
List* pList = (List*)malloc(sizeof(List));
if(NULL == pList)
{
return NULL;
}
memset(pList,0,sizeof(List));
pList->size = SIZE;
pList->pData = (data *)malloc(SIZE * sizeof(data_t));
if(NULL == pList->pData)
{
return NULL;
}
memset(pList->pData,0,sizeof(data_t)*SIZE);
pList->count = 0;
` return pList;
}
/*
*功能:插入一个元素到顺序表中,空间不够重新申请
*参数:pList顺序表首地址;iOffset要插入元素的位置; tData要插入的元素
*返回值:失败-1,成功0
*/
int insertItemList(List* pList,int iOffset,data_t tData)
{
//入参检查
if(NULL==pList||iOffset<0||iOffset>pList->count)
{
return -1;
}
// 顺序表满时,申请更大的空间
if(pList->count == pList->size)
{
int size = pList->size;
pList->size += 5;
data_t *pTemp = (data_t*)malloc(sizeof(data_t)*pList->size);
if(NULL == pTemp)
{
return -1;
}
memset(pTemp,0,sizeof(data_t)*pList->size);
//将原来空间的内容拷贝到新空间
memcpy(pTemp,pList->pData,sizeof(data_t)*size);
//将原来的空间释放
free(pList->pData);
pList->pData = pTemp;
}
int i;
for(i=pList->count;i>iOffset;i--)
{
pList->PData[i] = pList->pData[i-1];
}
pList->pData[iOffset] = tData;
pList->count++;
return 0;
}
/*
* 功能:删除一个元素
* pList 顺序表的首地址
* iOffset 要删除位置的下标
* pData 保存删除的元素
*/
int deleteItemList(List *pList, int iOffset, data_t *pData)
{
if(NULL == pList || iOffset < 0 || iOffset >= pList->count || 0 == pList->count)
{
return -1;
}
int i;
*pData = pList->pData[iOffset];
for(i = iOffset; i < pList->count-1; i++)
{
pList->pData[i] = pList->pData[i+1];
}
pList->count--;
return 0;
}
/*
*功能:销毁顺序表
*参数:List**ppList
*返回值: 无
*/
void destoryList(List **ppList)
{
if(NULL == ppList || NULL == *ppList)
{
return;
}
free(*ppList);
*ppList = NULL;
}
单向链表
逻辑结构:一对一
存储结构:不连续
节点由数据域与指针域组成
typedef struct data
{
int a;
char arr[10];
}Data_t; //数据结构体
typedef struct Node
{
Data_t data;
struct Node* pNext;//下一个节点的地址
}Node; //节点结构体
typedef struct Link
{
Node *pHead;//第一个节点的地址
int count; //节点个数
}Link; //单链表结构体
//头部插入
Node* pNode = NULL;
Link* pLink = NULL;
pNode->pNext = pLink->pHead;
pLink->pHead = pNode;
//中间插入(第iOffset个节点),前一个节点为pTemp
Node* pTemp = pLink->PHead;
for(i = 0;i<iOffst-1;i++)
{
pTemp = pTemp->pNext;
}
pNode->pNext = pTemp->pNext;
pTemp->pNext = pNode;
//尾插
pTemp = pLink->pHead;
for(i = 0;i<count;i++)
{
pTemp = pTemp->pNext;
}
pTemp->pNext = pNode;
//中间节点删除iOffset
Node* pTemp = pLink->PHead;
for(i = 0;i<iOffst-1;i++)
{
pTemp = pTemp->pNext;
}
Node *pDel = pTemp->pNext;
pTemp->pNext = pDel->pNext;
free(pDel);
pDel = NULL;
/*此处为伪代码,未写边界条件判断条件,写时要加上不然会段错误*/
双向链表
节点由数据域与指针域<上一个节点的地址、下一个节点的地址>组成
typedef struct data
{
int a;
char b[10];
}Data_t; //数据结构体
typedef struct node
{
struct Node* pPri;//上一个节点地址
Data_t data; //数据
struct Node* pNext;//下一个节点地址
}Node; //节点结构体
typedef struct pDLink
{
Node* pHead;
int count;
}Dlink;// 双向链表结构体
//头部插入
Node * pNode = NULL;
Dlink* pDlink = NULL;
pNode->pNext = pDlink->pHead;
pDlink->ppHead->pPri = pNode;
pDlink->pHead = pNode;
//中间插<iOffset>先找到前一个节点pTemp
Node * pTemp =pDlink->pHead;
for(i=0;i<iOffset-1;i++)
{
pTemp = pTemp->pNext;
}
pNode->pNext = ptemp->pNext;
pTemp->pNext->pPri = pNode;
pTemp->pNext = pNode;
pNode->pPri = pTemp;
//尾插
pTemp = pDlink->pHead;
for(i = 0;i<count-1;i++)
{
pTemp = pTemp->pNext;
}
pNode->pPri = pTemp;
pTemp->pNext = pNode;
//中间删(iOffset)找到前一个节点pTemp
pDel = pTemp->pNext
pDel->pNext->pPri = ptemp
pTemp->pNext = pDel->pNext
count--;
/*此处为伪代码,未写边界情况判断条件,写时要加上不然会段错误*/
栈
遵循先进后出,,有顺序栈与链式栈((尾插+尾删)或(头插+头删)),只能在一端操作
栈顶下标iTop=-1
入栈iTop++; data[iTop] =Data;
出栈返回Data[iTop] ;iTop--;
typedef struct stack
{
Data_t data[SIZE];
int iTop;
}stack;
队列
遵循先进先出,有顺序队列与链式队列
typedef struct queue
{
data_t data[SIZE];
int iHead; //队头下标
int iTail;//队尾下标
int count; //队列元素个数
}
//入队
if(count == SIZE)
{
printf("满了\r\n);
return 0
}
data[iTail] = data;
iTail++;
count++;
if(iTail == SIZE )
{iTail = 0}
//出队
if(count == 0)
{
printf("没了");
return 0 ;
}
*data = data[iHead];
iHead++;
count--;
if(iHead == SIZE )
{iHead = 0}
二叉树
哈希查找
排序算法
<1>冒泡排序
int i , j;
char arr[5] ={5,3,6,7,1};
for(i=0;i<4;i++)
{
for(j =0;j<4-i;j++)
{
if(arr[j]<arr[j+1])
{
char temp = arr[j+1];
arr[j+1] = arr[j];
arr[j] = temp;
}
}
}
<2>插入排序
//从第二个元素开始,把元素值保存下来,让其与前一个元素比较,如果前一个大于它,将前一个元素后移一位,在与前前一个元素比较,直到前一个元素小于它或到达了第一个元素结束,将保存下来的值存到小于他的元素后面。-----有点像打牌,拿一张牌从右向左(大到小)依次比较,将其插入到小于他的右边
char arr[6]={2,6,3,4,5,1};
int len = strlen(arr);
int i,j;
for(i=1;i<len;i++)
{
int key = arr[i];
j = i-1;
while(j>=0 && arr[j]>arr[j+1])
{
arr[j+1] = arr[j];
j--;
}
arr[j+1] = key;
}
<3>快速排序
//将首元素下标与尾元素下标记下(i与j),把首元素保存起来(x),用它与最后一个元素进行比较,如果最后一个元素大于他,j--用前一个元素继续比较,直到小于他,将此小于他的元素存到首位处即arr[i]处并i++;用此时i处的元素与x比较,如果arr[i]<x,i++,用后一个元素继续比较,如果arr[i]>x,将此处的arr[i]存到arr[j]处并j--;
//最后i=j时,把一开始保存的x存到arr[i],此时arr[i]左边小于他,右边的大于他,左边的元素下标为x-1,右边的下标为x+1,
//利用递归把左边的这一段用上面的方法再来一遍,此时首元素下标不变,尾元素下标为x-1;把由边的这一段用上面的方法再来一遍,此时尾元素下标不变,首元素下标为x+1,
char arr[10] = {4,2,5,1,3,6,8,6,9,15};
void speed(char *arr,int p,int q)
{
if(p<q)
{
int i=p;//首元素下标
int j=q;//尾元素下标
char x = arr[i];
while(i<j)
{
while(i<j&arr[j]>=x)
{j--;}
if(i<j){arr[i]= arr[j]; i++}
while(i<=j&arr[i]<x)
{i++;}
if(i<j){arr[j]= arr[i]; j--}
}
arr[i]=x;
speed(arr,p,i-1);
speed(arr,i+1,q);
}
return;
}
<4>选择排序
//设第一个成员为最小值,那后面的每一个与第一个比较,如果有比其更小的,将其下标记下,遍历比较完成后将最小的与第一个交换
char arr[6] = {5,3,2,9,4,1};
int len = strlen(arr);
int i,j;
for(i=0;i<len-1;i++)
{
int min = i;
for(j=i+1;j<len-i;j++)
{
if(arr[j]<arr[min])
{
min = j
}
}
char temp = arr[min];
arr[min] = arr[i];
arr[i] = temp;
}