1、心里话与大家分享
在代码中所有的注释都是在我第一次自己做的时候,没做对产生了错误之后找到了错误的原因而注释,我相信大家并不是每一句代码都不明白,而是往往和我一样,在某一个地方很疑惑,或者不解,因此,我认为没有必要每一句都注释。我是用耿国华的C语言学习的,我相信我的一些问题也许是大家的一些问题,因此,我很高兴和大家一起分享我的学习心得,让我们一起进步,畅游在算法与数据结构之美中,冲冲冲。
2、单向链表结构的实现以及基本功能
/**
* 在本节我们来学习线性单链表
*/
#include<stdio.h>
#include <mm_malloc.h>
#define MAXSIZE 15 // 常量的定义不需要分号也不需要等号 MAXSIZE = 5; 这样是错误的
#define OK 1
#define ERROR -1
#define NOTFOUND -2
typedef struct Node{
char data;
struct Node *next;
}Node,*LinkList;
int main(){
LinkList creatLinkList();
void createFromHead(LinkList L);
void dispaly(LinkList L);
void createFormTail(LinkList L);
int getLinkListLength(LinkList L);
int insert(LinkList L ,char elem,int index);
int delete(LinkList L ,int index);
int getElem(LinkList L,int index);
int getIndex(LinkList L,char elem);
LinkList *L = creatLinkList();
/* createFromHead(L);*/
createFormTail(L);
dispaly(L);
printf("长度:%d\n",getLinkListLength(L));
insert(L,'v',1);
delete(L,4);
getElem(L,1);
getIndex(L,'a');
dispaly(L);
}
//初始化单向链表
LinkList creatLinkList(){
Node *p = (Node *)malloc(sizeof(Node));
p->next = NULL;
return p;
};
//头插法建立单向表
void createFromHead(LinkList L){
Node *p;
char c;
int flag = 1;
while(flag){
c = getchar();
if (c != '$'){
p = (Node *)malloc(sizeof(Node));
p->data = c ;
p->next = L->next;
L->next = p;
}else{
flag = 0;
}
}
}
//尾插法建立单向表
void createFormTail(LinkList L){
Node *p,*r;
r = L;
char c;
int flag = 1;
while(flag){
c = getchar();
if (c != '$'){
p = (Node *)malloc(sizeof(Node));
p->data = c;
r->next = p;
r = p;
}else{
r->next = NULL;
flag = 0;
}
}
}
//遍历单向链表
void dispaly(LinkList L){
Node *p = L;
while (p->next != NULL){
p = p->next;
printf("%c\t",p->data);
}
}
//得到单向链表的长度
int getLinkListLength(LinkList L) {
Node *p = L;
int length = 0;
while (p->next != NULL) {
p = p->next;
length++;
}
return length;
}
//插入数据 返回1表示成功,-1表示失败
int insert(LinkList L ,char elem,int index){
//插入为位置小于1肯定是不对的,毫无疑问的
if (index < 1){
printf("输入的位置不对!");
return ERROR;
}
Node *pre,*r;
pre = L;
int j = 0;
/* //一直遍历找到 插入位置的前一个节点
while(pre->next != NULL){
pre = pre->next;
j++;
if (j == index-1){
r = (Node *)malloc(sizeof(Node));
r->data = elem;
r->next = pre->next;
pre->next = r;
return OK;
}
}*/ //不要按照这样子写,这样子写的话,当你插入一个位置时,就会报错
while(pre != NULL && j < index-1){//这是成立的条件,当遍历完还没找到插入的位置或者是找到插入的位置都跳出循环
pre = pre ->next;
j++;
}
if (pre == NULL){ //由于while循环结束肯能是因为pre ==NULL造成的所以要判断一下
printf("插入的位置过大!");
return ERROR;
}
//到达这一步肯定是意味着来到了
r = (Node *)malloc(sizeof(Node));
r->data = elem;
r->next = pre->next;
pre->next = r;
return OK;
}
/**
* 你应该会注意到插入是 pre != NULL && j < index-1
* 然后删除是 pre->next != NULL && k <index-1
* 那是因为插入数据的时候你可以插入到末尾,因此,这个时候即使是pre->next == NULL条件也是成立的
* 所以以后如果pre-next == NULL对于末尾不成立那就用这个作为条件,如果成立那么就用pre == NULL作为条件
*/
//移除数据
int delete(LinkList L ,int index){
Node *pre,*r;
pre = L;
int k = 0;
if (index < 1){
printf("要删除的位置不对!");
return ERROR;
}
while(pre->next != NULL && k <index-1 ){
pre = pre->next;
k++;
}
if (pre->next == NULL){
printf("要删除的位置过大!");
return ERROR;
}
r = pre->next;
pre->next = r->next;
free(r);//释放要删除的节点 刚开始没想到释放 我就直接写 pre->next = pre->next->next
return OK;
}
//按序号查找
int getElem(LinkList L,int index){
if (index < 1){
printf("输入的位置不对!");
return ERROR;
}
Node *p;
p = L;
int j = 0;
while(p->next != NULL){
p = p->next;
j++;
if (j == index){
printf("位置%d 对应的数据为:%c\n",index,p->data);
return p->data;
}
}
return ERROR;
}
//按值查找
int getIndex(LinkList L,char elem){
Node *p;
p = L;
int index = 0;
while(p->next != NULL){
p = p->next;
index++;
if (p->data == elem ){
printf("数据 %c 在表中的位置为:%d\n",p->data,index);
return index;
}
}
return ERROR;
}