单链表
先做一些准备工作,主要是增强代码的可读性:
//线性表的动态存储结构 #include<iostream> #include<stdlib.h> #define LIST_INIT_SIZE 100//线性表存储空间的初始分配量 #define LISTINCREMENT 10//线性表存储空间的分配增量 typedef int ElemType; typedef int Status; const int OVERFLOW = -2; const int OK = 1; const int ERROR = 0;
定义结点的结构体:
typedef struct LNode{ ElemType data; struct LNode *next; }LNode,*LinkList;
创建单链表:
void CreateList_L(LinkList &L,int n){ L=(LinkList)malloc(sizeof(LNode)); L->next=NULL; for(int i=n;i>0;i--){ p=(LinkList)malloc(sizeof(LNode)); scanf(&p->data); p->next=L->next; L->next=p; } }
获取第i个元素的值:
Status GetElem_L(LinkList L,int i,ElemType&e){ LinkList p; p=L->next; int j=1; while(p&&j<1){ p=p->next; j++; } if(!p||j>i){ return ERROR; } e=p->data; return OK; }
在第i个位置上插入一个值:
Status ListInsert_L(LinkList &L,int i,ElemType e){ LinkList p; p=L; int j=0; while(p&&j<i-1){ p=p->next; j++; } if(!p||j>i-1){ return ERROR; } s=(LinkList)malloc(sizeof(LNode)); s->data=e; s->next=p->next; p->next=s; return OK; }
删除第i个元素的值:
status ListDelete_L(LinKList &L,int i,ElemType &e){ LinkList p=L; int j=0; while(p->next&&j<i-1){ p=p->next; j++; } if(!(p->next)||j>i-1){ return ERROR; } q=p->next; p->next=q->next; e=q->data; free(q); }
合并两个有序的链表,使合并后仍然有序:
void MergeList_L(LinkList&La,LinkList&Lb,LinkList&Lc){ LinkList pa=La->next; LinkList pb=Lb->next; LinkList pc; Lc=pc=La;//用La的头结点作为Lc的头结点 while(pa&&pb){ if(pa->data<=pb->data){ pc->next=pa;//将pa以后的链接到Lc最后的结点上 pc=pa;// pa=pa->next; }else{ pc->next=pb; pc=pb; pb=pb->next; } } pc->next=pa?pa:pb; free(Lb); }
这个链表的合并到底是一个怎样的操作???
pc->next是指向它下一个数据元素的指针,让下一个数据元素的指针指向等于pa
然后又让pc等于指针pa(这一个是什么意思,我有些看不懂)
对于pa=pa->next我倒是没有什么疑问,它的作用就是让La链表向前挪一位。
上面没想懂的那个现在想懂了,我画了几个图应该可以表述是怎么回事
pc->next=pa;的作用是将Lc的指针域改为指针pa所指向的空间
循环链表
特点:表中最后一个结点的指针域指向头结点,整个链表的首位结点相连形成一个环
从循环链表中的任何结点出发都能找到其他结点
与单链表的区别:遍历链表的终止条件不同
单链表终止条件是指针域为空
循环链表终止条件是指向表头结点
双向链表
int ( *compare )( ElemType, ElemType ) 函数指针,返回为int类型,两个参数类型都是ElemType
bool LocateElem(OrderedLinkList, ElemType , int (*compare)( ElemType, ElemType));
注意这个函数,它会调用
compare(ElemType,ElemType); 当一个函数传入时,那么就调用被传入的函数
下面是函数指针的简单用法
int fun(int i){ return i+5; }
int main()
{
int (*pfun)(int);
pfun=&fun; //取函数地址,然后传给pfun
pfun(5); //和函数调用方法一样,这里就相当于调用fun(5)
}