//线性表的链式存储:单链表
#include<stdio.h>
#include<stdlib.h>
typedef int DataType;
typedef struct Node
{
DataType data; //数据域
struct Node *next; //指针域
}ListNode,*LinkList;
//将单链表初始化为空。动态生成一个头结点,并将头结点的指针域置为空
void InitList(LinkList *head){
if((*head=(LinkList)malloc(sizeof(ListNode)))==NULL)
exit(-1);
(*head)->next=NULL;
}
//判断单链表是否为空,就是通过判断头结点的指针域是否为空
int ListEmpty(LinkList head){
if(head->next==NULL)
return 1;
else
return 0;
}
//查找单链表中第i个结点。查找成功返回该结点的指针表示成功;否则返回NULL表示失败
ListNode *Get(LinkList head,int i){
ListNode *p;
int j;
if(ListEmpty(head))
return NULL;
if(i<1)
return NULL;
j=0;
p=head;
while(p->next!=NULL&&j<i){
p=p->next;
j++;
}
if(j==i)
return p;
else
return NULL;
}
//查找线性表中元素值为e的元素,查找成功将对应元素的结点指针返回,否则返回NULL表示失败
ListNode *LocateElem(LinkList head,DataType e){
ListNode *p;
p=head->next;
while(p){
if(p->data!=e)
p=p->next;
else
break;
}
return p;
}
//查找线性表中元素值为e的元素,查找成功将对应元素的序号返回,否则返回0表示失败
int LocatePos(LinkList head,DataType e){
ListNode *p;
int i;
if(ListEmpty(head))
return 0;
p=head->next;
i=1;
while(p){
if(p->data==e)
return i;
else{
p=p->next;
i++;
}
}
if(!p)
return 0;
}
//在单链表中第i个位置插入一个结点,结点的元素值为e。插入成功返回1,失败返回
int InsertList(LinkList head,int i,DataType e){
ListNode *p,*pre;
int j;
pre=head;
j=0;
while(pre->next!=NULL&&j<i-1){
pre=pre->next;
j++;
}
if(!pre){
printf("wrong place\n");
return 0;
}
if((p=(LinkList)malloc(sizeof(ListNode)))==NULL)
exit(-1);
p->data=e;
p->next=pre->next;
pre->next=p;
return 1;
}
//删除单链表中的第i个位置的结点。删除成功返回1,失败返回0
int DeleteList(LinkList head,int i,DataType *e){
ListNode *pre,*p;
int j;
pre=head;
j=0;
while(p->next!=NULL&&pre->next->next!=NULL&&j<i-1){
pre=pre->next;
j++;
}
if(j!=i-1){
printf("delete wrong place\n");
return 0;
}
p=pre->next;
pre->next=p->next;
free(p);
return 1;
}
int ListLength(LinkList head){
ListNode *p;
int count=0;
p=head;
while(p->next!=NULL){
p=p->next;
count++;
}
return count;
}
void DestroyList(LinkList head){
ListNode *p,*q;
p=head;
while(p!=NULL){
q=p;
p=p->next;
free(q);
}
}
//*****************************************************
//删除A中出现B的元素的函数
void DelElem(LinkList A,LinkList B){
int i,pos;
DataType e;
ListNode *p;
//在单链表B中,取出每个元素与单链表A中的元素比较,如果相等则删除A中元素对应的结点
for(i=0;i<=ListLength(B);i++){
p=Get(B,i);//取出B中的每个结点,将指针返回给p
if(p){
pos=LocatePos(A,p->data);//比较B中的元素是否与A中的元素相等
if(pos>0)
DeleteList(A,pos,&e);//如果相等,将其从A中删除
}
}
}
void DelElem2(LinkList A,LinkList B){
ListNode *pre,*p,*r,*q;
pre=A;
p=A->next;
//在单链表B中,取出每个元素与单链表A中的元素比较,如果相等则删除A中元素对应的结点
while(p!=NULL){
q=B->next;
while(q!=NULL&&q->data!=p->data)
q=q->next;
if(q!=NULL){
r=p;
pre->next=p->next;
p=r->next;
free(r);
}else{
pre=p;
p=p->next;
}
}
}
void main_DelElem(){
int i;
DataType a[]={2,3,6,7,9,14,56,45,65,67};
DataType b[]={3,4,7,11,34,54,45,67};
LinkList A,B; /*声明单链表A和B*/
ListNode *p;
InitList(&A); /*初始化单链表A*/
InitList(&B); /*初始化单链表B*/
for(i=1;i<=sizeof(a)/sizeof(a[0]);i++) /*将数组a中元素插入到单链表A中*/
{
if(InsertList(A,i,a[i-1])==0)
{
printf("位置不合法\n");
return;
}
}
for(i=1;i<=sizeof(b)/sizeof(b[0]);i++) /*将数组b中元素插入单链表B中*/
{
if(InsertList(B,i,b[i-1])==0)
{
printf("位置不合法\n");
return;
}
}
printf("单链表A中的元素有%d个:\n",ListLength(A));
for(i=1;i<=ListLength(A);i++) /*输出单链表A中的每个元素*/
{
p=Get(A,i); /*返回单链表A中的每个结点的指针*/
if(p)
printf("%4d",p->data); /*输出单链表A中的每个元素*/
}
printf("\n");
printf("单链表B中的元素有%d个:\n",ListLength(B));
for(i=1;i<=ListLength(B);i++)
{
p=Get(B,i); /*返回单链表B中的每个每个结点的指针*/
if(p)
printf("%4d",p->data); /*输出单链表B中的每个元素*/
}
printf("\n");
DelElem2(A,B); /*将在单链表A中出现的B的元素删除,即A-B*/
printf("将在A中出现B的元素删除后(A-B),现在A中的元素还有%d个:\n",ListLength(A));
for(i=1;i<=ListLength(A);i++)
{
p=Get(A,i); /*返回单链表A中每个结点的指针*/
if(p)
printf("%4d",p->data); /*显示输出删除后A中所有元素*/
}
printf("\n");
system("pause");
}
//**************************************************
//单链表A和B中的元素非递减排列,将单链表A和B中的元素合并到C中,C中的元素仍按照非递减排列
void MergeList(LinkList A,LinkList B,LinkList *C){
ListNode *pa,*pb,*pc;
pa=A->next;
pb=B->next;
*C=A;//将单链表A的头结点作为C的头结点
(*C)->next=NULL;
pc=*C;
//依次将链表A和B中较小的元素存入链表C中
while(pa&&pb){
if(pa->data<=pb->data){
pc->next=pa;//如果A中的元素小于或等于B中的元素,将A中的元素的结点作为C的结点
pc=pa;
pa=pa->next;
}else{
pc->next=pb;//如果A中的元素大于B中的元素,将B中的元素的结点作为C的结点
pc=pb;
pb=pb->next;
}
}
pc->next=pa?pa:pb;//将剩余的结点插入C中
free(B);//释放B的头结点
}
void main_MergeList(){
int i;
DataType a[]={6,7,9,14,37,45,65,67};
DataType b[]={3,7,11,34,45,89};
LinkList A,B,C; /*声明单链表A和B*/
ListNode *p;
InitList(&A); /*初始化单链表A*/
InitList(&B); /*初始化单链表B*/
for(i=1;i<=sizeof(a)/sizeof(a[0]);i++) /*将数组a中元素插入到单链表A中*/
{
if(InsertList(A,i,a[i-1])==0)
{
printf("位置不合法\n");
return;
}
}
for(i=1;i<=sizeof(b)/sizeof(b[0]);i++) /*将数组b中元素插入单链表B中*/
{
if(InsertList(B,i,b[i-1])==0)
{
printf("位置不合法\n");
return;
}
}
printf("单链表A中的元素有%d个:\n",ListLength(A));
for(i=1;i<=ListLength(A);i++) /*输出单链表A中的每个元素*/
{
p=Get(A,i); /*返回单链表A中的每个结点的指针*/
if(p)
printf("%4d",p->data); /*输出单链表A中的每个元素*/
}
printf("\n");
printf("单链表B中的元素有%d个:\n",ListLength(B));
for(i=1;i<=ListLength(B);i++)
{
p=Get(B,i); /*返回单链表B中的每个每个结点的指针*/
if(p)
printf("%4d",p->data); /*输出单链表B中的每个元素*/
}
printf("\n");
MergeList(A,B,&C); /*将单链表A和B中的元素合并到C中*/
printf("将单链表A和B的元素合并到C中后,C中的元素有%d个:\n",ListLength(C));
for(i=1;i<=ListLength(C);i++)
{
p=Get(C,i); /*返回单链表C中每个结点的指针*/
if(p)
printf("%4d",p->data); /*显示输出C中所有元素*/
}
printf("\n");
system("pause");
}
//**************************************************
//逆置链表
void ReverseList(LinkList H){
ListNode *p,*q;
p=H->next; //p指向链表的第一个结点
H->next=NULL;
while(p){ //利用头插法将结点依次插入到链表的头部
q=p->next;
//
p->next=H->next;
H->next=p;
p=q;
}
}
//输出链表
void DisplayList(LinkList L){
int i;
ListNode *p;
for(i=0;i<=ListLength(L);i++){
p=Get(L,i);
if(p)
printf("%4d",p->data);
}
printf("\n");
}
void main_ReverseList(){
int a[]={1,2,3,4,5,6,7,8,9,10};
int i;
LinkList L;
InitList(&L); /*初始化单链表L*/
for(i=1;i<=sizeof(a)/sizeof(a[0]);i++) /*将数组a中元素插入到单链表L中*/
{
if(InsertList(L,i,a[i-1])==0)
{
printf("位置不合法");
return;
}
}
printf("逆置前链表中的元素:\n");
DisplayList(L);
ReverseList(L);
printf("逆置后链表中的元素:\n");
DisplayList(L);
system("pause");
}
void main(){
main_DelElem();
main_MergeList();
main_ReverseList();
}