C版本
View Code
1 #include<stdio.h> 2 #include<stdlib.h> 3 #define DataType int 4 #define FLAG -1 5 typedef struct Node 6 { 7 DataType data; 8 struct Node *next; 9 }Lnode,*LinkList; 10 11 LinkList Creat_LinkList() 12 { 13 LinkList L; 14 Lnode *s,*r; 15 int x; 16 printf("建立有表头结点的单链表,以%d作为创建链表完成的标志\n",FLAG); 17 L=r=s=NULL; 18 L=(Lnode *)malloc(sizeof(Lnode)); 19 if(!L) 20 { 21 printf("表头结点开辟失败\n"); 22 exit(-1); 23 } 24 L->next=NULL; 25 scanf("%d",&x); 26 while(x!=FLAG) 27 { 28 s=(Lnode *)malloc(sizeof(Lnode)); 29 if(!s) 30 { 31 printf("结点开辟失败\n"); 32 exit(-1); 33 } 34 s->data=x; 35 if(NULL==L->next)//第一个结点的处理 36 L->next=s; 37 else 38 r->next=s; 39 r=s; 40 scanf("%d",&x); 41 } 42 if(r!=NULL)//对于非空表,最后结点的指针域放空指针 43 r->next=NULL; 44 return L; 45 } 46 /*有头结点的链表,求表长算法*/ 47 int Length_LinkList(LinkList L) 48 { 49 Lnode *p; 50 int j; 51 p=L; 52 j=0; 53 while(p->next) 54 { 55 p=p->next; 56 j++; 57 } 58 return j; 59 } 60 int Print_LinkList(LinkList L) 61 { 62 printf("输出:\n"); 63 Lnode *s; 64 s=L; 65 while(s->next!=NULL) 66 { 67 s=s->next; 68 printf("%3d",s->data); 69 } 70 printf("\n"); 71 return 0; 72 } 73 /*逆置算法思路: 74 依次取原链表中每个结点,将其作为第一个结点插入到新的 75 链表中去。指针p用来指向原表中当前结点,p为空时结束。*/ 76 void Reverse_LinkList(LinkList H)//单链表的逆置 77 { 78 Lnode *p,*q; 79 p=H->next;//p指向第一个结点 80 H->next=NULL;//将原链表置为空表 81 while(p) 82 { 83 q=p; 84 p=p->next; 85 q->next=H->next;//将当前节点插入到头结点后面 86 H->next=q; 87 } 88 return; 89 } 90 91 /*按序号查找*/ 92 Lnode *Get_LinkList(LinkList L,int i) 93 { 94 Lnode *p; 95 int j=0; 96 p=L; 97 while(p->next!=NULL&&j<i) 98 { 99 p=p->next; 100 j++; 101 } 102 if(j==i) 103 return p; 104 else 105 return NULL; 106 } 107 /*按值查找*/ 108 Lnode *Locate_LinkList(LinkList L,DataType x) 109 { 110 Lnode *p; 111 p=L->next; 112 while(p!=NULL&&p->data!=x) 113 p=p->next; 114 return p; 115 } 116 /*插入操作,分为:前插接点、后插结点.下面的算法实现在链表的第i个位置上插入一个数值 117 118 后插结点:设p指向单链表中某结点,s指向待插入值为x的新结点,将*s插入到*p之后, 119 操作:s->next=p->next;p->next=s; 120 前插接点:遇红茶结点不同德是,这种算法要先找到前驱结点*q,然后完成在*q后插入*s, 121 操作:q=L;while(q->next!=p)q=p->next;s->next=q->next;q->next=s;*/ 122 int Insert_LinkList(LinkList L,int i,DataType x) 123 { 124 Lnode *p,*s; 125 p=Get_LinkList(L,i-1); 126 if(NULL==p) 127 { 128 printf("前驱结点不存在,不能插入\n"); 129 return 0; 130 } 131 else 132 { 133 s=(Lnode *)malloc(sizeof(Lnode)); 134 s->data=x; 135 s->next=p->next; 136 p->next=s; 137 return 1; 138 } 139 } 140 141 /*按序号删除结点*/ 142 int Del_LinkList(LinkList L,int i) 143 { 144 Lnode *p,*s; 145 p=Get_LinkList(L,i-1); 146 if(NULL==p) 147 { 148 printf("你要删除的结点前驱结点不存在\n"); 149 return -1; 150 } 151 else 152 if(NULL==p->next) 153 { 154 printf("第%d个结点不存在\n",i); 155 return 0; 156 } 157 else 158 { 159 s=p->next; 160 p->next=s->next; 161 free(s); 162 return 1; 163 } 164 } 165 /*按值删除结点,为了使算法清晰,只删除找到的第一个结点*/ 166 int Remove_LinkList(LinkList L,DataType x) 167 { 168 Lnode *p,*s; 169 p=Locate_LinkList(L,x);//找到要删除的结点 170 if(NULL==p) 171 { 172 printf("你要删除的结点不存在\n"); 173 return -1; 174 } 175 s=L; 176 while(s->next!=p) 177 s=s->next;//找到要删除结点的前驱 178 s->next=p->next; 179 free(p); 180 return 1; 181 } 182 int main() 183 { 184 Lnode *L,*p; 185 int n,m,k; 186 L=Creat_LinkList(); 187 Print_LinkList(L); 188 printf("表长(头结点不计算在内):%d\n",Length_LinkList(L)); 189 printf("按序号查找,请输入你要查找的结点的序号:\n"); 190 scanf("%d",&n); 191 p=Get_LinkList(L,n); 192 if(NULL==p) 193 printf("未找到\n"); 194 else 195 printf("找到了,该结点存放的数据:%d\n",p->data); 196 printf("按值查找,请输入你要查找的数据:\n"); 197 scanf("%d",&n); 198 p=Locate_LinkList(L,n); 199 if(NULL==p) 200 printf("未找到\n"); 201 else 202 printf("找到了\n"); 203 printf("插入结点,请输入你要插入的位置和数值\n"); 204 scanf("%d%d",&k,&n); 205 m=Insert_LinkList(L,k,n); 206 if(0==m) 207 printf("前驱结点不存在不能插入\n"); 208 else if(1==m) 209 printf("插入成功\n"); 210 Print_LinkList(L); 211 printf("表长(头结点不计算在内):%d\n",Length_LinkList(L)); 212 printf("按序号删除,请输入你要删除的结点的序号:\n"); 213 scanf("%d",&n); 214 m=Del_LinkList(L,n); 215 if(-1==m) 216 printf("你要删除的结点无前驱结点\n"); 217 else if(0==m) 218 printf("你要删除的结点不存在\n"); 219 else if(1==m) 220 printf("删除成功\n"); 221 Print_LinkList(L); 222 printf("表长(头结点不计算在内):%d\n",Length_LinkList(L)); 223 printf("按值删除,请输入你要删除的数据:\n"); 224 scanf("%d",&n); 225 m=Remove_LinkList(L,n); 226 if(-1==m) 227 printf("你要删除的结点无前驱结点\n"); 228 else if(0==m) 229 printf("你要删除的结点不存在\n"); 230 else if(1==m) 231 printf("删除成功\n"); 232 Print_LinkList(L); 233 printf("表长(头结点不计算在内):%d\n",Length_LinkList(L)); 234 Reverse_LinkList(L); 235 printf("逆置后:\n"); 236 Print_LinkList(L); 237 return 0; 238 }
C++版本
//File: LinkNode.h //Author: Jason #ifndef LINKNODE_H_ #define LINKNODE_H_ template<typename Type> struct LinkNode//结点类定义 { Type data;//数据元素 LinkNode<Type> *pnext;//链表指针域 //构造函数 //仅初始化指针成员的构造函数 LinkNode(LinkNode<Type> *next = NULL):pnext(next){} //初始化数据和指针成员的构造函数 LinkNode(const Type &item, LinkNode<Type> *next = NULL):data(item),pnext(next){} }; #endif
View Code
//File: SingleLinkList.h //Author: Jason #ifndef SINGLELINKLIST_H_ #define SINGLELINKLIST_H_ #include<iostream> using namespace std; #include<assert.h> #include<stdlib.h> #include"LinkNode.h" template<typename Type> class SingleLinkList//单链表定义 { public: //构造函数 SingleLinkList(LinkNode<Type> *node = NULL):phead(new LinkNode<Type>(node)){ } SingleLinkList(Type & x){ phead = new LinkNode<Type>(x);} SingleLinkList(SingleLinkList &list);//复制构造函数 ~SingleLinkList(){ setEmpty();}//析构函数 public: LinkNode<Type> *getHead(){ return phead; }//返回链表的头结点 LinkNode<Type> *getRear();//获得链表的尾结点 LinkNode<Type> *Locate(int i);//搜索第i个元素的地址 LinkNode<Type> *Search(const Type &x);//搜索含数据x的元素 void setEmpty();//将链表设置为空 int getlength()const;//计算链表的长度 //判断表是否为空,空则返回true bool isEmpty()const{ return phead->pnext == NULL ? true : false; } bool isFull()const{ return false;}//判断表是否为满,满则返回false bool getData(int i, Type &x);//取出第i个元素的值 bool setData(int i, Type &x);//用x修改第i个元素的值 bool Insert(Type &x,int i=0);//在第i个元素后插入x bool Remove(Type &x,int i=0);//删除第i个元素,x返回该元素的值 bool InsertHead(Type &x);//在第1个元素前插入x,即有头结点之后插入 bool InsertRear(Type &x);//在链表的最后后插入x bool RemoveHead(Type &x);//将链表中的最后一个元素删去,通过引用型参数x返回该元素的值 bool RemoveRear(Type &x);//将链表中的最后一个元素删去,通过引用型参数x返回该元素的值 void output()const;//输出链表中的元素 SingleLinkList<Type> &operator=(SingleLinkList &list);//赋值重载函数 //友元函数,操作符重载 friend ostream& operator<<<Type>(ostream& os,const SingleLinkList<Type>& list); private: LinkNode<Type> *phead;//声明头结点 }; template<typename Type> SingleLinkList<Type>::SingleLinkList(SingleLinkList<Type> &list)//复制构造函数 { Type value; LinkNode<Type> *srcnode = list.getHead();//被复制的附加头结点地址 LinkNode<Type> *destnode = new LinkNode<Type>(); while(srcnode->pnext!=NULL)//逐个结点复制 { value = srcnode->pnext->data; destnode->pnext = new LinkNode<Type>(value); destnode = destnode->pnext; srcnode = srcnode->pnext; } destnode->pnext = NULL; } template<typename Type> void SingleLinkList<Type>::setEmpty()//将链表设置为空 { LinkNode<Type> *pDel; while(phead->pnext!=NULL)//当链表不为空时删去链表中所有结点 { pDel = phead->pnext;//保存被删除的结点,从链上取下该结点 phead->pnext = pDel->pnext;//删除,仅保留头结点 delete pDel; } } template<typename Type> int SingleLinkList<Type>::getlength() const//计算带附加结点的单链表的长度 { LinkNode<Type> *pMove = phead->pnext; int nCount = 0; while(pMove!=NULL)//链表扫描,寻找链尾 { nCount++; pMove = pMove->pnext; } return nCount; } template<typename Type> LinkNode<Type> *SingleLinkList<Type>::getRear()//获得链表的尾结点 { LinkNode<Type> *pMove = phead; while(pMove->pnext!=NULL) { pMove = pMove->pnext; } return pMove; } template<typename Type> LinkNode<Type> *SingleLinkList<Type>::Locate(int i) {//定位函数,返回表中第i个元素的地址,若i<0或i超出表中结点个数,则返回NULL if( i < 0 ) return NULL;//i不合理 LinkNode<Type> *pMove = phead; int k = 0; while(pMove->pnext!=NULL && k<i)//寻找第i个结点 { pMove = pMove->pnext; k++; } //返回第i个结点地址,若返回NULL,表示i值太大或太小 return pMove; } template<typename Type> LinkNode<Type> *SingleLinkList<Type>::Search(const Type &x) {//在表中搜索含数据x的结点,搜索成功时函数返回该结点的地址,否则返回NULL值 LinkNode<Type> *pCurrent = phead->pnext; while(pCurrent==NULL) { if(pCurrent->data != x)//循环链找含x的结点 break; else pCurrent = pCurrent->pnext; } return pCurrent; } template<typename Type> bool SingleLinkList<Type>::getData(int i, Type &x) {//取出链表中第i个元素的值 LinkNode<Type> *pCurrent = Locate(i); if(pCurrent==NULL||pCurrent==phead) return false;//i不合理 x = pCurrent->data; return true; } template<typename Type> bool SingleLinkList<Type>::setData(int i, Type &x) {//给链表中第i个元素赋值 LinkNode<Type> *pCurrent = Locate(i); if(pCurrent==NULL||pCurrent==phead) return false;//i不合理 pCurrent->data = x; return true; } template<typename Type> bool SingleLinkList<Type>::Insert(Type &x, int i)//在第i个元素后插入x { LinkNode<Type> *pCurrent = Locate(i); if(pCurrent==NULL) return false; LinkNode<Type> *newNode = new LinkNode<Type>(x); assert(newNode!=NULL); newNode->pnext = pCurrent->pnext; pCurrent->pnext = newNode; return true; } template<typename Type> bool SingleLinkList<Type>::InsertHead(Type &x) //即insert(0,x) {//在第1个元素前插入x,即有头结点之后插入 LinkNode<Type> *newNode = new LinkNode<Type>(x); assert(newNode!=NULL); newNode->pnext = phead->pnext; phead->pnext = newNode; return true; } template<typename Type> bool SingleLinkList<Type>::InsertRear(Type &x) {//在链表的最后后插入x LinkNode<Type> *prear = getRear(); LinkNode<Type> *newNode = new LinkNode<Type>(x); assert(newNode!=NULL); newNode->pnext = prear->pnext; prear->pnext = newNode; return true; } template<typename Type> bool SingleLinkList<Type>::Remove(Type &x, int i) {//将链表中的第i个元素删去,通过引用型参数x返回该元素的值 LinkNode<Type> *pCurrent = Locate(i-1); if(pCurrent==NULL||pCurrent->pnext==NULL) return false; LinkNode<Type> *pDel; pDel = pCurrent->pnext;//重新拉链,将被删除的结点从链表中取出 pCurrent->pnext = pDel->pnext; x = pDel->data;//取出被删除结点中的数据值 delete pDel; return true; } template<typename Type> bool SingleLinkList<Type>::RemoveHead(Type &x) {//将链表中的第1个元素删去,通过引用型参数x返回该元素的值 LinkNode<Type> *pDel; if(phead->pnext==NULL) return false; pDel = phead->pnext; phead->pnext = pDel->pnext; x = pDel->data; delete pDel; return true; } template<typename Type> bool SingleLinkList<Type>::RemoveRear(Type &x) {//将链表中的最后一个元素删去,通过引用型参数x返回该元素的值 if(phead->pnext==NULL) return false; LinkNode<Type> *pCurrent = phead; while(pCurrent->pnext->pnext!=NULL) { pCurrent = pCurrent->pnext; } LinkNode<Type> *pDel; pDel = pCurrent->pnext; pCurrent->pnext = pDel->pnext; x = pDel->data; delete pDel; return true; } template<typename Type> void SingleLinkList<Type>::output()const//输出链表中的元素 { LinkNode<Type> *pMove = phead; cout << "Head->"; while(pMove->pnext!=NULL) { pMove = pMove->pnext; cout << pMove->data << "->"; } cout << "End" << endl; } template<typename Type> SingleLinkList<Type> &SingleLinkList<Type>::operator=(SingleLinkList &list) {//操作符重载 Type value; LinkNode<Type> *srcnode = list.getHead(); LinkNode<Type> *destnode = new LinkNode<Type>(); while(srcnode->pnext!=NULL) { value = srcnode->pnext->data; destnode->pnext = new LinkNode<Type>(value); destnode = destnode->pnext; srcnode = srcnode->pnext; } destnode->pnext = NULL; return *this; } template<typename Type> ostream& operator<<(ostream& os,SingleLinkList<Type>& list) //友元函数,操作符重载 {//输出链表中元素的重载操作符<< os << "The length of the list is: " << list.getlength() << endl; // the size of stack is ouputing! LinkNode<Type> *pMove = list.getHead(); os << "Head->"; while(pMove->pnext!=NULL) //The menmber of the stack is outputing respectively! { pMove = pMove->pnext; os << pMove->data << "->"; } os << "End" << endl; return os; } #endif
View Code
//Fle: Main.cpp //Author: Jason #include<iostream> #include"SingleLinkList.h" using namespace std; int main() { SingleLinkList<int> list; list.setEmpty(); //测试空链表的长度 cout << "The length of the list is " << list.getlength() << endl; if(list.isEmpty()) cout << "The list is Empty! " << endl; else cout << "The list is Not Empty! " << endl; //向链表表中插入元素 for(int i=0; i<10; i++) { int temp = 2*i; list.Insert(temp,i); cout << temp << " has been inserted ! \n"; cout << "Output the list:\n"; list.output(); cout << "The length of the list is " << list.getlength() << endl; cout << endl; } //查看特定位置的元素并进行修改 int data; list.getData(5,data); cout << "The fifth number in the list is " << data << endl; data = 100; list.setData(5,data); list.output(); cout << "The fifth number in the list is modfied by " << data << endl; cout << endl; //删除链表元素 for(int i=10; i>0; i--) { int temp = 0; list.Remove(temp,i); cout << temp << " has been deleted ! \n"; cout << "Output the list:\n"; list.output(); cout << "The length of the list is " << list.getlength() << endl; cout << endl; } //向链表利用前插法在链表头部插入元素 for(int i=0; i<5; i++) { int temp = 3*i; list.InsertHead(temp); cout << temp << " has been inserted at the head ! \n"; cout << "Output the list:\n"; list.output(); cout << "The length of the list is " << list.getlength() << endl; cout << endl; } //向链表利用后插法在链表的尾部插入元素 for(int i=0; i<5; i++) { int temp = 3*i; list.InsertRear(temp); cout << temp << " has been inserted at the end ! \n"; cout << "Output the list:\n"; list.output(); cout << "The length of the list is " << list.getlength() << endl; cout << endl; } //从链表头部开始删除元素 for(int i=0; i<5; i++) { int temp; list.RemoveHead(temp); cout << temp << " has been deleted ! \n"; cout << "Output the list:\n"; list.output(); cout << "The length of the list is " << list.getlength() << endl; cout << endl; } //从链表尾部开始删除元素 for(int i=0; i<5; i++) { int temp; list.RemoveRear(temp); cout << temp << " has been deleted ! \n"; cout << "Output the list:\n"; cout << list; cout << endl; } return 0; }