标签:
单链表的创建算法
当一个序列中只含有指向它的后继结点的链接时,就称该链表为单链表。
单链表的示意图如下:
Head指针为单链表的头指针,单链表L:L既是单链表的名字,也是其头指针。链表中的最后一个结点的指针域定义为空指针(NULL)。
单链表的定义:
struct Node { ElemType data; struct Node *next; }; typedef struct Node LNode; typedef struct Node *LinkedList;单链表有带头结点和不带头结点之分。
上图为没有头结点的单链表,下图为带有头结点的单链表:
//不带头结点的单链表的初始化 void LinkedListInit1(LinkedList L) { L=NULL; } //带头结点的单链表的初始化 void LinkedListInit2(LinkedList L) { L=(LNode *)malloc(sizeof(LNode)); if(L==NULL) { printf("申请空间失败!"); exit(0); } L->next=NULL; }
//带头结点的单链表求表长 int LinkedListLength(LinkedList L) { LNode *p; //p需要声明为LNode类型 p=L->next; int j=0; while(p!=NULL) { j++; p=p->next; //将p向下移动一个结点 } return j; }
//带头结点的单链表取元素操作 LinkedList LinkedListGetINode(LinkedList L, int i) { LNode *p; p=L->next; int j=1; while((p!=NULL)&&(j<i)) { p=p->next; j++; } return p; }
//带头结点的单链表定位操作 LNode LinkedListLocateE(LinkedList L, ElemType e) { LNode *p; p=L->next; while((p!=NULL)&&(p->data!=e)) { p=p->next; } return p; }
2)在链表的中间插入
(1)创建一个新的结点q。
(2)将此结点的数据域赋值为e,并将它的next指针指向p。
(3)查找到p的前驱结点pre。
(4)将pre的next指针指向新创建的结点q。
操作示意图如下:
//不带头结点的单链表的插入操作 void LinkedListInertQE1(LinkedList L, LinkedList p, ElemType e) { q=(LNode *)malloc(sizeof(LNode)); //创建一个新的结点q if(q==NULL) { printf("申请空间失败!"); exit(0); } q->data=e; if(p==L) //在表头插入 { q->next=L; L=q; } else //在表的中间进行插入 { pre=L; while((pre!=NULL)&&(pre->next!=p)) //寻找p的前驱 pre=pre->next; q->next=pre->next; pre->next=q; } } //带头结点的单链表的插入操作 void LinkedListInertQE2(LinkedList L, LinkedList p, ElemType e) { q=(LNode *)malloc(sizeof(LNode)); //创建一个新的结点q if(q==NULL) { printf("申请空间失败!"); exit(0); } q->data=e; //插入新的结点 pre=L; while((pre!=NULL)&&(pre->next!=p)) //寻找p的前驱 pre=pre->next; q->next=pre->next; pre->next=q; }
2)p是链表中的其他结点
(1)找到p的前驱结点pre。
(2)将pre->next指向p->next。
(3)释放p。
示意图如下:
//不带头结点的单链表的删除操作 void LinkedListDeleteQE1(LinkedList L, LinkedList p, ElemType e) { pre=L; while((pre!=NULL)&&(pre->next->data!=e)) //查找元素e的前驱 pre=pre->next; p=pre->next; if(p!=NULL) //找到需要删除的结点 { if(p==L) //删除的是第一个结点 L=p->next; else //删除的是其他结点 pre->next=p->next; free(p); } } //带头结点的单链表的删除操作 void LinkedListDeleteQE2(LinkedList L, LinkedList p, ElemType e) { pre=L; while((pre!=NULL)&&(pre->next->data!=e)) //查找元素e的前驱 pre=pre->next; p=pre->next; if(p!=NULL) //找到需要删除的结点 { pre->next=p->next; free(p); } }
尾插法是将新增结点插入最后一个结点之后,示意图如下:
//用头插法创建带头结点的单链表 void LinkedListCreateHeadL(LinkedList L, ElemType a[n]) { L=(LNode *)malloc(sizeof(LNode)); if(L==NULL) { printf("申请空间失败!"); exit(0); } L->next=NULL; for(i=0; i<n; i++) { p=(LNode *)malloc(sizeof(LNode)); if(p==NULL) { printf("申请空间失败!"); exit(0); } p->data=a[i]; p->next=L->next; L->next=p; } } //用尾插法创建带头结点的单链表 void LinkedListCreateTailL(LinkedList L, ElemType a[n]) { L=(LNode *)malloc(sizeof(LNode)); if(L==NULL) { printf("申请空间失败!"); exit(0); } L->next=NULL; tail=L; //设置尾指针,方便插入 for(j=0; j<n; j++) { p=(LNode *)malloc(sizeof(LNode)); if(p==NULL) { printf("申请空间失败!"); exit(0); } p->data=a[j]; p->next=NULL; tail->next=p; tail=p; } }
//带头结点的单链表合并操作 void LinkedListMergeLaLb(LinkedList La, LinkedList Lb, LinkedList Lc) { pa=La->next; pb=Lb->next; Lc=La; //借用表La的头结点作为表Lc的头结点 pc=Lc; while((pa!=NULL)&&(pb!=NULL)) { if(pa->data<=pb->data) { pc->next=pa; pc=pa; pa=pa->next; } else { pc->next=pb; pc=pb; pb=pb->next; } } if(pa!=NULL) pc=pa->next; else pc=pb->next; free(pb); //将Lb的表头结点释放 }本文根据:清华大学出版社《数据结构与算法(C语言版)(第3版)》整理,详细请见书本。
程序实例:尾插法创建单链表
首先在VS2010中新建Win32 控制台应用程序的项目LinkedList,结果如下:
LinkedList.cpp : 定义控制台应用程序的入口点。
// LinkedList.cpp : 定义控制台应用程序的入口点。 #include "stdafx.h" #include<stdio.h> #include<stdlib.h> typedef struct node { int data; struct node *next; }*LinkedList; LinkedList LinkedListCreateTailL(int a[8]) { LinkedList p, L, tail; int i=0; L=(struct node*)malloc(sizeof(struct node)); tail=L; for(i=0; i<8; i++) { p=(struct node*)malloc(sizeof(struct node)); p->data=a[i]; tail->next=p; tail=p; } tail->next=NULL; return L; } void LinkedListPrint(LinkedList L) { LinkedList p; p=L->next; while(p!=NULL) { printf("%d ",p->data); p=p->next; } } void main() { int a[8], i; LinkedList L; printf("请输入8个列表元素,以回车结束:\n"); for(i=0; i<8; i++) { scanf("%d", &a[i]); } L=LinkedListCreateTailL(a); LinkedListPrint(L); }Ctrl+F5执行以上cpp文件,程序运行截图:
标签:
原文地址:http://blog.csdn.net/wp1603710463/article/details/50989500