单链表即线性表的链式存储结构,也叫线性链表。其特点是用一组任意的存储单元来保存数据,链表的每个节点分为数据域和指针域。数据域用来保存数据信息,指针域用来指示下一个节点的存储单元地址。
从上可以看出:
1)单链表有一个头结点,要查找某个节点时从该节点出发查找。
2)要删除某个位置的节点,可以通过修改该节点的前驱节点的指针域和该节点的指针域相同,这样其前驱节点将会直接指向下一个节点(当然,删除之后要调用free函数来释放)
3)要在某个位置插入一个节点,同删除,只需新建一个节点元素,然后将要插入位置的前驱节点的指针域指向新节点元素的地址,并将该节点的指针域指向插入位置的节点。
定义单链表的结构为:
#define ElemType int typedef struct LNode{ ElemType data; //单链表每个节点保存的数据 即数据域 struct LNode *next; //单链表的指向下一个节点的指针 即指针域 }LNode,Linklist;
分别实现链表的创建,插入,删除,查找
创建:
/* 函数名:Linklist_creat 函数功能:建立带表头节点L的单链表 函数返回:返回表头节点的地址 */ Linklist* Linklist_creat(ElemType e) { Linklist *L; L=(LNode*)malloc(sizeof(LNode)); //为表头节点分配内存 L->next=NULL; //将头结点的指针域赋值为null L->data=e; //头结点指针域赋值 return L; }
插入代码:
/* 函数名: Linklist_insert 函数功能:在单链表的某个位置插入一个元素 函数返回:返回插入的结果EROOR失败,OK成功, */ int Linklist_insert(Linklist *L, int i,ElemType e) { Linklist *p = L; for(;i>0&&p->next!=NULL;i--) { p=p->next; //移动头指针指向第i个节点 } if(p->next==NULL&&i!=0) //即L已经指向最后一个节点而位置还没调整到第i个节点,则i不合法 { return ERROR; } else if(p->next==NULL&&i==0) //即L已经指向最后一个节点而位置刚好调整到第i个节点,即在链表的尾部添加一个节点 { LNode* NewNode=(LNode*)malloc(sizeof(LNode)); NewNode->data=e; NewNode->next=NULL; p->next=NewNode; return OK; } else if(p->next!=NULL&&i==0) //即向两个节点中插入一个新的节点 { LNode* NewNode=(LNode*)malloc(sizeof(LNode)); NewNode->data=e; NewNode->next=p->next; p->next=NewNode; return OK; } }
删除:
/* 函数名: Linklist_delete 函数功能:删除单链表第i个位置的元素 函数返回:若成功删除,返回删除元素的值,否则返回ERROR */ ElemType Linklist_delete(Linklist *L, int i) { Linklist *p = L; ElemType e; for (i=i-2; i>0 && p->next != NULL; i--) //这里的i-2~~~~~如要删除第2个节点,p应当指向第一个节点,故p移动一次,则条件为(i-1)-1 { p = p->next; //移动指针指向第i个节点的前一个节点 } if (p->next == NULL&&i != 0) //即L已经指向最后一个节点而位置还没调整到第i个节点,则i不合法 { exit(0); } else if (p->next == NULL&&i == 0) //即L已经指向最后一个节点而位置刚好调整到第i个节点的前一个节点,即删除链表尾部的一个节点 { e = p->next->data; free(p->next); p->next = NULL; return e; } else if (p->next != NULL&&i == 0) //即删除两个节点中的一个节点 { Linklist *tmp = p->next; e = p->next->data; p->next = p->next->next; //调整已删除节点的前驱节点的指针域 free(tmp); //释放要删除的节点的存储空间 return e; } }
查找:
/* 函数名:Linklist_GetElm 函数功能:得到单链表中某个位置的元素,并将其返回 函数返回:返回单链表某个位置的值 */ ElemType Linklist_GetElm(Linklist *L, int i) //得到单链表中某个位置的元素,并将其返回 { Linklist *p = L; for (i=i-1; i>0 && p->next != NULL; i--) //要得到第i个位置的数据,需要头结点移动i-1次 { p = p->next;//移动头指针指向第i个节点 } return p->data; }