顺序表
了解顺序表的前提就是知道什么是线性表,线性表的概念非常的简单,就是除了头和尾元素之外的所有元素都有一个前驱和一个后继,满足这样要求的我们基本上都可以定义为线性表。
那么线性表我们在这里会讲述其中的两种
顺序线性表----逻辑和物理位置都是相邻的线性表叫做顺序表。
那么废话我们就谈到这,给出一个顺序表的代码,但是还是未完成版,我在网上看到他们给出了一个顺序表的完整版(18个函数)我就完成了其中的几个。。
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#define maxsize 10
typedef struct
{
int data[maxsize];
int last;
}sqlist;//顺序表定义
sqlist *inti_sqlist()
{
sqlist *l;
l = (sqlist *)malloc(sizeof(sqlist));
l->last = -1;
return l;
}// 初始化
int find_element_location(sqlist *l,int elem)
{
int i=0;
while(i<l->last&&l->data[i]!=elem)
i++;
if (i>l->last)
return -1;
else
return i;
}//查找数据元素的位置
int insert_element(sqlist *l,int i,int elem)
{
if (l->last==maxsize-1)
{
printf("the list is full!\n");
return -1;
}
if (i<1||i>l->last+2)
{
printf("wrong location!\n");
return 0;
}
for (int j=l->last;j>=i-1;j--)
l->data[j+1] = l->data[j];
l->data[i-1]=elem;
l->last++;
return 1;
}
int delete_element(sqlist *l,int i)
{
if (i<1||i>l->last+1)
{
printf("wrong location\n");
return -1;
}
for (int j=i;j<l->last;j++)
l->data[j]=l->data[j+1];
l->last--;
return 1;
}
void show(sqlist *l,int n)
{
printf("the element of the sqlist is:\n");
for (int i=0;i<n;i++)
{
printf("%d\t",l->data[i]);
}
printf("\n");
}
void createlist(sqlist *l,int n)
{
for (int i=0;i<n;i++)
{
printf("please input the elem of list:");
scanf("%d",&l->data[i]);
l->last++;
}
}
int main()
{
sqlist *l;
int number;
int elem,position;
l = inti_sqlist();
printf("please input how many number do you want to:\n");
scanf("%d",&number);
createlist(l,number);
show(l,number);
while(1)
{
printf("please input the elem:");
scanf("%d",&elem);
fflush(stdin);
if (elem==000)
{
printf("the choose is quit!\n ");
break;
}
printf("please input where do you want to insert:");
scanf("%d",&position);
fflush(stdin);
insert_element(l,position,elem);//增加一个元素
//printf("%d\n",l->last);
number++;
show(l,number);
}
while(1)
{
int position;
printf("please input which one do you want to delete:");
scanf("%d",&position);
fflush(stdin);
delete_element(l,position);
number--;
show(l,number);
}
system("pause");
return 0;
}
代码不难,很简单,不分析!!

链表
我们一般对链表可以讲有以下一些情况,单链表,循环链表,双向链表
单链表顾名思义,就是从头开始,不能回溯,一切都是从头开始。
循环链表就是在在单链表的基础上,使得最后一个元素的指针不是指向空而是指向第一个元素。
双线链表单链表的基础上加了一个指向前驱的一个指针。
代码之伺候:
#include <stdlib.h>
#include <stdio.h>
#include <malloc.h>
typedef int elemtype;
typedef struct node
{
elemtype elem;
struct node *next;
}LNode,*linkList;
//初始化一个空链表
linkList InitLinkList()
{
LNode *L;
L=(LNode *)malloc(sizeof(LNode));
if (L==NULL)
printf("申请空间失败!\n");//如果申请空间失败的话,表明不正确
L->next=NULL;//空表头指针指向空
return 0;
}
//从头插入建立一个单链表
linkList create_linklist_by_head()
{
LNode *L;
L = (LNode *)malloc(sizeof(LNode));
if (L==NULL)
printf("申请空间失败!\n");//如果申请空间失败的话,表明不正确
L->next=NULL;//空表头指针指向空
elemtype x;
LNode *s;
printf("please input a element:");
while(scanf("%d",&x)!=EOF)
{
s=(LNode *)malloc(sizeof(LNode));
s->elem = x;
s->next = L->next;
L->next = s;
printf("please input a element:");
}
return L;
}
//从尾插入建立一个单链表
linkList create_linklist_by_rear()
{
LNode *L;
L = (LNode *)malloc(sizeof(LNode));
if (L==NULL)
printf("申请空间失败!\n");//如果申请空间失败的话,表明不正确
L->next=NULL;//空表头指针指向空
LNode *rear;//设定一个尾指针
rear = L;
elemtype x;
LNode *s;
printf("please input a element:");
while(scanf("%d",&x)!=EOF)
{
s=(LNode *)malloc(sizeof(LNode));
s->elem = x;
rear->next = s;
rear=s;
printf("please input a element:");
}
rear->next = NULL;
return L;
}
//求单链表的长度
int length_of_linklist(linkList L)
{
int length=0;
LNode *head;
head = L;
while(head->next!=NULL)
{
head = head->next;
length++;
}
return length;
}
//按序号查询单链表
LNode *search_by_ID(linkList L,int i)
{
LNode *head = L;
int j=0;
while(head->next!=NULL&&j<i)
{
head = head->next;
j++;
}
if (j==i)
return head;
else
return NULL;
}
//按值查询单链表
int search_by_value(linkList L,elemtype x)
{
LNode *head = L;
int j=0;
while(head->next!=NULL && head->elem!=x)
{
head = head->next;
j++;
}
if (head->elem==x)
return j;
else
return -1;
}
//单链表的前插
linkList list_insert_before(LNode *L,int i,elemtype elem)
{
LNode *head,*s;
head = L;
s = (LNode *)malloc(sizeof(LNode));
s->elem = elem;
s->next = search_by_ID(L,i-1)->next;//做了个小把戏,前插就是前一个元素的后插(没含金量)
search_by_ID(L,i-1)->next = s;
return L;
}
//单链表的后插
linkList list_insert_after(LNode *L,int i,elemtype elem)
{
LNode *head = L;
LNode *s;
s = (LNode *)malloc(sizeof(LNode));
s->elem = elem;
s->next = search_by_ID(L,i)->next;
search_by_ID(L,i)->next = s;
return L;
}
linkList delete_elem(linkList L,elemtype x)
{
LNode *head;
head = L->next;
LNode *s;
while(head->elem!=x)
{
s = head;
head = head->next;
}
s->next = head->next;
free(head);
return L;
}
void show(linkList list)
{
linkList start;
//list = InitLinkList();
for(start = list->next;start!=NULL;start=start->next)
printf("%d\t",start->elem);
}
int main()
{
linkList list;
int position;
elemtype elem;
list = InitLinkList();
printf("请输入单链表的数据:\n");
//list = create_linklist_by_head();
list = create_linklist_by_rear();
show(list);
printf("单链表长度是:%d\n",length_of_linklist(list));
/////////////////////////////////////////////////////////////////////验证search_by_ID
printf("输入你想查询的位置:");
scanf("%d",&position);
if(search_by_ID(list,position))
printf("你查询的位置的元素是:%d\n",search_by_ID(list,position)->elem);
else
printf("没有这个元素");
///////////////////////////////////////////////////////////////////验证search_by_value
printf("输入你想查询的元素:");
scanf("%d",&elem);
if(search_by_value(list,elem)!=-1)
printf("你查询的元素位置是:%d\n",search_by_value(list,elem));
else
printf("没有这个元素");
///////////////////////////////////////////////////////////后插法
printf("输入你想插入的位置:");
scanf("%d",&position);
printf("输入你想插入的元素:");
scanf("%d",&elem);
fflush(stdin);
list_insert_after(list,position,elem);
show(list);
printf("\n");
////////////////////////////////////////////////////////前插法
printf("输入你想插入的位置:");
scanf("%d",&position);
printf("输入你想插入的元素:");
scanf("%d",&elem);
fflush(stdin);
list_insert_before(list,position,elem);
show(list);
printf("\n");
/////////////////////////////////////////删除元素
printf("输入你想删除的位置:");
scanf("%d",&position);
delete_elem(list,position);
show(list);
printf("\n");
system("pause");
return 0;
}
分的情况比较多,其实核心的东西非常的少,非常的少,就是加入了一些情况,什么前插后插啊,头插尾插啊之类的,代码就显得冗余了!!!
串
其实这个概念可以不说的,因为C++中有个类叫string,这个类基本上把C语言中的串中的所有功能全实现了,而且还添加了很多的功能,所以,我感觉太多的研究这个意义不是特别的大。
这里讲一下KMP算法,就我个人而言,我到现在为止还没有搞明白这个算法,尤其是其中的next函数的求法,网上给的方法五花八门,我没有搞定,有大神有好的方法或者是帖子希望不吝赐教!!
也把代码放在这,但是有bug
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
int strIndex_KMP(char *s,char *t,int position)//KMP算法
{
int i=position,j=1,slen,tlen;
while(i<=s[0]&&j<=t[0])
if (j==0||s[i]==t[j])
{
i++;
j++;
}
if (j>t[0])
return i-t[0];
else
return -1;
}
void getNext(char *ss,int next[])//next函数
{
next[1] = 0;
int j=1,k=0;
while(j<ss[0])
{
if ((k==0)||(ss[j]==ss[k]))
{
j++;
k++;
next[j] = k;
}
else
k = next[k];
}
/*next[0]=-1;
int k=-1,j=0;
while(pattern[j]!='\0')
{
while(k!=-1&&pattern[k]!=pattern[j])k=next[k];
++j;
++k;
if(pattern[k]==pattern[j])
next[j]=next[k];
else next[j]=k;
}*/
}
int main()
{
char *s = "aabcbabcaabcaababc";
char *t = " abaabcac";
int tlength = strlen(t);
printf("the length of string t is %d\n",tlength);
int *next = (int *)malloc(tlength*sizeof(int));
//int next[9]={0};
for (int i=0;i<tlength;i++)
{
next[i] = 0;
}
//int next[9];
getNext(t,next);
printf("the array of next is:\n");
for(int i=0;i<tlength;i++)
printf("%d\t",next[i]);
printf("the position of finding is:%d\n",strIndex_KMP(s,t,0));
system("pause");
return 0;
}
