单链表类型描述typedef char DataType; //假设结点的数据域类型为字符 typedef struct node{ //结点类型定义 DataType data; //结点的数据域 struct node *next;//结点的指针域 }ListNode; typedef ListNode *LinkList; ListNode *p; LinkList head;①生成结点变量的标准函数 p=( ListNode *)malloc(sizeof(ListNode)); //函数malloc分配一个类型为ListNode的结点变量的空间,并将其首地址放入指针变量p中 ②释放结点变量空间的标准函数 free(p);//释放p所指的结点变量空间 ③结点分量的访问 利用结点变量的名字*p访问结点分量 方法一:(*p).data和(*p).next 方法二:p-﹥data和p-﹥next(1) 头插法建表 LinkList CreatListF(void) {//返回单链表的头指针 char ch; LinkList head;//头指针 ListNode *s; //工作指针 head=NULL; //链表开始为空 //head->next=NULL; ch=getchar(); //读入第1个字符 while(ch!='/n'){ s=(ListNode *)malloc(sizeof(ListNode));//生成新结点 s->data=ch; //将读入的数据放入新结点的数据域中 s->next=head; //s->next=head->next; head=s; // head->next=s; 红处修改为带头结点当然前面需要定义结点空间,这样效果更好 ch=getchar(); //读入下一字符 } return head; } (2) 尾插法建表 LinkList CreatListR(void) {//返回单链表的头指针 char ch; LinkList head;//头指针 ListNode *s,*r; //工作指针 head=NULL; //链表开始为空 r=NULL;//尾指针初值为空 ch=getchar(); //读入第1个字符 while(ch!='/n'){ s=(ListNode *)malloc(sizeof(ListNode));//生成新结点 s->data=ch; //将读入的数据放入新结点的数据域中 if (head!=NULL) head=s;//新结点插入空表 else r->next=s;//将新结点插到*r之后 r=s;//尾指针指向新表尾 ch=getchar(); //读入下一字符 }//endwhile if (r!=NULL) r->next=NULL;//对于非空表,将尾结点指针域置空head=s; return head; } (3) 尾插法建带头结点的单链表 LinkList CreatListR1(void) {//用尾插法建立带头结点的单链表 char ch; LinkList head=(ListNode *)malloc(sizeof(ListNode));//生成头结点 ListNode *s,*r; //工作指针 r=head; // 尾指针初值也指向头结点 while((ch=getchar())!='/n'){ s=(ListNode *)malloc(sizeof(ListNode));//生成新结点 s->data=ch; //将读入的数据放入新结点的数据域中 r->next=s; r=s; //个人觉得这里没对!s->next应该也有指向 } r->next=NULL;//终端结点的指针域置空,或空表的头结点指针域置空 return head; } (1)按序号查找 ListNode* GetNode(LinkList head,int i) {//在带头结点的单链表head中查找第i个结点,若找到(0≤i≤n), //则返回该结点的存储位置,否则返回NULL。 int j; ListNode *p; p=head;j=0;//从头结点开始扫描 while(p->next&&j<i){//顺指针向后扫描,直到p->next为NULL或i=j为止 p=p->next; j++; } if(i==j) return p;//找到了第i个结点 else return NULL;//当i<0或i>0时,找不到第i个结点 } (2) 按值查找 ListNode* LocateNode (LinkList head,DataType key) {//在带头结点的单链表head中查找其值为key的结点 ListNode *p=head->next;//从开始结点比较。表非空,p初始值指向开始结点 while(p&&p->data!=key)//直到p为NULL或p->data为key为止 p=p->next;//扫描下一结点 return p;//若p=NULL,则查找失败,否则p指向值为key的结点 }3.插入运算 void InsertList(LinkList head,DataType x,int i) {//将值为x的新结点插入到带头结点的单链表head的第i个结点的位置上 ListNode *p; p=GetNode(head,i-1);//寻找第i-1个结点 if (p==NULL)//i<1或i>n+1时插入位置i有错 Error("position error"); s=(ListNode *)malloc(sizeof(ListNode)); s->data=x;s->next=p->next;p->next=s; } 4.删除运算 void DeleteList(LinkList head,int i) {//删除带头结点的单链表head上的第i个结点 ListNode *p,*r; p=GetNode(head,i-1);//找到第i-1个结点 if (p==NULL||p->next==NULL)//i<1或i>n时,删除位置错 Error("position error");//退出程序运行 r=p->next;//使r指向被删除的结点ai p->next=r->next;//将ai从链上摘下 free(r);//释放结点ai的空间给存储池 }